prototxt-parser
Version:
a prototxt parser for js based on parsimmon
83 lines (82 loc) • 2.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var P = require("parsimmon");
var removeLineComments = function (d) { return d.filter(function (e) {
return Array.isArray(e);
}); };
var tuplesToObj = function (d) { return d.reduce(function (r, c) {
var key = c[0], val = c[1];
r[key] = r.hasOwnProperty(key) ? [].concat(r[key], val) : val;
return r;
}, {}); };
var interpretEscapes = function (str) {
var escapes = {
b: "\b",
f: "\f",
n: "\n",
r: "\r",
t: "\t"
};
return str.replace(/\\(u[0-9a-fA-F]{4}|[^u])/, function (_, escape) {
var type = escape.charAt(0);
var hex = escape.slice(1);
if (type === "u") {
return String.fromCharCode(parseInt(hex, 16));
}
if (escapes.hasOwnProperty(type)) {
return escapes[type];
}
return _;
});
};
var whitespace = P.regexp(/\s*/m);
var token = function (parser) { return parser.skip(whitespace); };
var word = function (str) { return P.string(str).thru(token); };
var Prototxt = P.createLanguage({
value: function (r) {
return P.alt(r.number, r.null, r.true, r.false, r.string, r.identifier)
.thru(function (parser) { return whitespace.then(parser); })
.desc("value");
},
identifier: function () {
return token(P.regexp(/[a-zA-Z_-][a-zA-Z0-9_+-]*/)
.desc("identifier"));
},
lbrace: function () { return word("{"); },
rbrace: function () { return word("}"); },
colon: function () { return word(":"); },
null: function () { return word("null").result(null); },
true: function () { return word("true").result(true); },
false: function () { return word("false").result(false); },
comment: function () { return P.regexp(/\s*#\s*(.*)/m, 1); },
doubleQuotedString: function () { return P.regexp(/"((?:\\.|.)*?)"/, 1); },
singleQuotedString: function () { return P.regexp(/'((?:\\.|.)*?)'/, 1); },
string: function (r) {
return token(P.alt(r.doubleQuotedString, r.singleQuotedString))
.map(interpretEscapes)
.desc("string");
},
number: function () {
return token(P.regexp(/-?(0|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?/))
.map(Number)
.desc("number");
},
pair: function (r) { return P.seq(r.identifier.skip(r.colon), r.value); },
message: function (r) {
return P.seq(r.identifier, r.colon.times(0, 1)
.then(r.lbrace)
.then(r.exp)
.skip(r.rbrace));
},
exp: function (r) {
return P.alt(r.pair, r.message, r.comment)
.trim(P.optWhitespace)
.many()
.map(removeLineComments)
.map(tuplesToObj);
}
});
function parse(input) {
return Prototxt.exp.tryParse(input);
}
exports.parse = parse;