pegisland
Version:
General PEG-based parser supporting island grammars with lake symbols
60 lines • 2.37 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.InitialPegBuilder = void 0;
// Copyright (C) 2021- Katsumi Okuda. All rights reserved.
const assert_1 = require("assert");
const ParsingExpression_1 = require("./ParsingExpression");
const Rule_1 = require("./Rule");
class InitialPegBuilder {
constructor() {
this.rules = new Map();
}
build(peg) {
this.rules = new Map();
Object.keys(peg).forEach((key) => this.rules.set(key, new Rule_1.Rule(key, new ParsingExpression_1.NullParsingExpression())));
Object.keys(peg).forEach((key) => {
const rule = this.rules.get(key);
rule.rhs = this.compileExpression(peg[key]);
});
return this.rules;
}
compileExpression(expression) {
if (typeof expression === 'string') {
return this.compileNonterminal(expression);
}
if (expression[0] === 'terminal') {
return this.compileTerminal(expression);
}
return this.compileOperator(expression);
}
compileOperator(expression) {
const [operator, ...subexpList] = expression;
const operands = subexpList.map((subexp) => this.compileExpression(subexp));
switch (operator) {
case '*':
return new ParsingExpression_1.ZeroOrMore(operands[0]);
case '+':
return new ParsingExpression_1.OneOrMore(operands[0]);
case '?':
return new ParsingExpression_1.Optional(operands[0]);
case '&':
return new ParsingExpression_1.And(operands[0]);
case '!':
return new ParsingExpression_1.Not(operands[0]);
case '':
return new ParsingExpression_1.Sequence(operands);
case '/':
return new ParsingExpression_1.OrderedChoice(operands);
}
}
compileTerminal([, pattern]) {
return new ParsingExpression_1.Terminal(pattern, `r"${pattern.source}"`);
}
compileNonterminal(expression) {
const nonterminal = expression;
(0, assert_1.strict)(this.rules.has(nonterminal));
return new ParsingExpression_1.Nonterminal(this.rules.get(nonterminal));
}
}
exports.InitialPegBuilder = InitialPegBuilder;
//# sourceMappingURL=InitialPegBuilder.js.map