Skip to content

Commit 369357a

Browse files
committed
enhance array parser
1 parent f2f3807 commit 369357a

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

lib/arrayParser.js

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
function ArrayParser(source, converter) {
2+
this.source = source;
3+
this.converter = converter;
4+
this.pos = 0;
5+
this.entries = [];
6+
this.recorded = [];
7+
this.dimension = 0;
8+
if (!this.converter) {
9+
this.converter = function(entry) {
10+
return entry;
11+
};
12+
}
13+
}
14+
ArrayParser.prototype.eof = function() {
15+
return this.pos >= this.source.length;
16+
};
17+
ArrayParser.prototype.nextChar = function() {
18+
var c;
19+
if ((c = this.source[this.pos++]) === "\\") {
20+
return {
21+
char: this.source[this.pos++],
22+
escaped: true
23+
};
24+
} else {
25+
return {
26+
char: c,
27+
escaped: false
28+
};
29+
}
30+
};
31+
ArrayParser.prototype.record = function(char) {
32+
return this.recorded.push(char);
33+
};
34+
ArrayParser.prototype.newEntry = function() {
35+
var entry;
36+
if (this.recorded.length > 0) {
37+
entry = this.recorded.join("");
38+
if (entry === "NULL") {
39+
entry = null;
40+
}
41+
if (entry !== null) {
42+
entry = this.converter(entry);
43+
}
44+
this.entries.push(entry);
45+
this.recorded = [];
46+
}
47+
};
48+
ArrayParser.prototype.parse = function(nested) {
49+
var c, p, quote;
50+
if (nested == null) {
51+
nested = false;
52+
}
53+
quote = false;
54+
while (!this.eof()) {
55+
c = this.nextChar();
56+
if (c.char === "{" && !quote) {
57+
this.dimension++;
58+
if (this.dimension > 1) {
59+
p = new ArrayParser(this.source.substr(this.pos - 1), this.converter);
60+
this.entries.push(p.parse(true));
61+
this.pos += p.pos - 2;
62+
}
63+
} else if (c.char === "}" && !quote) {
64+
this.dimension--;
65+
if (this.dimension === 0) {
66+
this.newEntry();
67+
if (nested) {
68+
return this.entries;
69+
}
70+
}
71+
} else if (c.char === '"' && !c.escaped) {
72+
if (quote) {
73+
this.newEntry();
74+
}
75+
quote = !quote;
76+
} else if (c.char === ',' && !quote) {
77+
this.newEntry();
78+
} else {
79+
this.record(c.char);
80+
}
81+
}
82+
if (this.dimension !== 0) {
83+
throw "array dimension not balanced";
84+
}
85+
return this.entries;
86+
};
87+
88+
module.exports = {
89+
create: function(source, converter){
90+
return new ArrayParser(source, converter);
91+
}
92+
}

0 commit comments

Comments
 (0)