93 lines
2.1 KiB
JavaScript
93 lines
2.1 KiB
JavaScript
function ArrayParser(source, converter) {
|
|
this.source = source;
|
|
this.converter = converter;
|
|
this.pos = 0;
|
|
this.entries = [];
|
|
this.recorded = [];
|
|
this.dimension = 0;
|
|
if (!this.converter) {
|
|
this.converter = function(entry) {
|
|
return entry;
|
|
};
|
|
}
|
|
}
|
|
ArrayParser.prototype.eof = function() {
|
|
return this.pos >= this.source.length;
|
|
};
|
|
ArrayParser.prototype.nextChar = function() {
|
|
var c;
|
|
if ((c = this.source[this.pos++]) === "\\") {
|
|
return {
|
|
char: this.source[this.pos++],
|
|
escaped: true
|
|
};
|
|
} else {
|
|
return {
|
|
char: c,
|
|
escaped: false
|
|
};
|
|
}
|
|
};
|
|
ArrayParser.prototype.record = function(char) {
|
|
return this.recorded.push(char);
|
|
};
|
|
ArrayParser.prototype.newEntry = function(includeEmpty) {
|
|
var entry;
|
|
if (this.recorded.length > 0 || includeEmpty) {
|
|
entry = this.recorded.join("");
|
|
if (entry === "NULL") {
|
|
entry = null;
|
|
}
|
|
if (entry !== null) {
|
|
entry = this.converter(entry);
|
|
}
|
|
this.entries.push(entry);
|
|
this.recorded = [];
|
|
}
|
|
};
|
|
ArrayParser.prototype.parse = function(nested) {
|
|
var c, p, quote;
|
|
if (nested == null) {
|
|
nested = false;
|
|
}
|
|
quote = false;
|
|
while (!this.eof()) {
|
|
c = this.nextChar();
|
|
if (c.char === "{" && !quote) {
|
|
this.dimension++;
|
|
if (this.dimension > 1) {
|
|
p = new ArrayParser(this.source.substr(this.pos - 1), this.converter);
|
|
this.entries.push(p.parse(true));
|
|
this.pos += p.pos - 2;
|
|
}
|
|
} else if (c.char === "}" && !quote) {
|
|
this.dimension--;
|
|
if (this.dimension === 0) {
|
|
this.newEntry();
|
|
if (nested) {
|
|
return this.entries;
|
|
}
|
|
}
|
|
} else if (c.char === '"' && !c.escaped) {
|
|
if (quote) {
|
|
this.newEntry(true);
|
|
}
|
|
quote = !quote;
|
|
} else if (c.char === ',' && !quote) {
|
|
this.newEntry();
|
|
} else {
|
|
this.record(c.char);
|
|
}
|
|
}
|
|
if (this.dimension !== 0) {
|
|
throw "array dimension not balanced";
|
|
}
|
|
return this.entries;
|
|
};
|
|
|
|
module.exports = {
|
|
create: function(source, converter){
|
|
return new ArrayParser(source, converter);
|
|
}
|
|
}
|