antlr-ng
Version:
Next generation ANTLR Tool
68 lines (67 loc) • 2.1 kB
JavaScript
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
import { LL1Analyzer, Token } from "antlr4ng";
import { disjoint } from "../support/helpers.js";
import { IssueCode } from "../tool/Issues.js";
import { LeftRecursionDetector } from "./LeftRecursionDetector.js";
import { Utils } from "../misc/Utils.js";
class AnalysisPipeline {
constructor(g) {
this.g = g;
}
static {
__name(this, "AnalysisPipeline");
}
process() {
const lr = new LeftRecursionDetector(this.g, this.g.atn);
lr.check();
if (lr.listOfRecursiveCycles.length !== 0) {
return;
}
if (this.g.isLexer()) {
this.processLexer();
} else {
this.processParser();
}
}
processLexer() {
for (const rule of this.g.rules.values()) {
if (rule.isFragment()) {
continue;
}
const analyzer = new LL1Analyzer(this.g.atn);
const look = analyzer.look(this.g.atn.ruleToStartState[rule.index], void 0);
if (look.contains(Token.EPSILON)) {
this.g.tool.errorManager.grammarError(
IssueCode.EpsilonToken,
this.g.fileName,
rule.ast.children[0].token,
rule.name
);
}
}
}
processParser() {
this.g.decisionLookahead = new Array(this.g.atn.getNumberOfDecisions() + 1);
for (const s of this.g.atn.decisionToState) {
this.g.tool.logInfo({
component: "LL1",
msg: "\nDECISION " + s.decision + " in rule " + this.g.getRule(s.ruleIndex)?.name
});
let look = [];
if (s.nonGreedy) {
look = new Array(s.transitions.length + 1);
} else {
const anal = new LL1Analyzer(this.g.atn);
look = anal.getDecisionLookahead(s);
this.g.tool.logInfo({ component: "LL1", msg: "look=" + look });
}
Utils.setSize(this.g.decisionLookahead, s.decision + 1);
this.g.decisionLookahead[s.decision] = look;
this.g.tool.logInfo({ component: "LL1", msg: "LL(1)? " + disjoint(look) });
}
}
}
export {
AnalysisPipeline
};