antlr-ng
Version:
Next generation ANTLR Tool
329 lines (328 loc) • 11.4 kB
JavaScript
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
import { ANTLRv4Parser } from "../generated/ANTLRv4Parser.js";
import { disjoint } from "../support/helpers.js";
import { LeftRecursiveRule } from "../tool/LeftRecursiveRule.js";
import { Action } from "./model/Action.js";
import { AddToLabelList } from "./model/AddToLabelList.js";
import { AltBlock } from "./model/AltBlock.js";
import { CodeBlockForAlt } from "./model/CodeBlockForAlt.js";
import { CodeBlockForOuterMostAlt } from "./model/CodeBlockForOuterMostAlt.js";
import { InvokeRule } from "./model/InvokeRule.js";
import { LL1AltBlock } from "./model/LL1AltBlock.js";
import { LL1OptionalBlock } from "./model/LL1OptionalBlock.js";
import { LL1OptionalBlockSingleAlt } from "./model/LL1OptionalBlockSingleAlt.js";
import { LL1PlusBlockSingleAlt } from "./model/LL1PlusBlockSingleAlt.js";
import { LL1StarBlockSingleAlt } from "./model/LL1StarBlockSingleAlt.js";
import { LeftRecursiveRuleFunction } from "./model/LeftRecursiveRuleFunction.js";
import { MatchNotSet } from "./model/MatchNotSet.js";
import { MatchSet } from "./model/MatchSet.js";
import { MatchToken } from "./model/MatchToken.js";
import { OptionalBlock } from "./model/OptionalBlock.js";
import { Parser } from "./model/Parser.js";
import { ParserFile } from "./model/ParserFile.js";
import { PlusBlock } from "./model/PlusBlock.js";
import { RuleFunction } from "./model/RuleFunction.js";
import { SemPred } from "./model/SemPred.js";
import { StarBlock } from "./model/StarBlock.js";
import { TestSetInline } from "./model/TestSetInline.js";
import { Wildcard } from "./model/Wildcard.js";
import { RuleContextDecl } from "./model/decl/RuleContextDecl.js";
import { TokenDecl } from "./model/decl/TokenDecl.js";
import { TokenListDecl } from "./model/decl/TokenListDecl.js";
class ParserFactory {
constructor(gen, forceAtn) {
this.forceAtn = forceAtn;
this.gen = gen;
this.g = gen.g;
}
static {
__name(this, "ParserFactory");
}
g;
controller;
gen;
parserFile(fileName, toolParameters) {
return new ParserFile(this, fileName, toolParameters);
}
parser(file) {
return new Parser(this, file);
}
lexerFile(fileName) {
return void 0;
}
getGrammar() {
return this.g;
}
lexer(file) {
return void 0;
}
rule(r) {
if (r instanceof LeftRecursiveRule) {
return new LeftRecursiveRuleFunction(this, r);
}
return new RuleFunction(this, r);
}
epsilon(alt, outerMost) {
return this.alternative(alt, outerMost);
}
alternative(alt, outerMost) {
if (outerMost) {
return new CodeBlockForOuterMostAlt(this, alt);
}
return new CodeBlockForAlt(this);
}
finishAlternative(blk, ops) {
blk.ops = ops ?? [];
return blk;
}
stringRef(id, label) {
return this.tokenRef(id, label, null);
}
action(ast) {
return [new Action(this, ast)];
}
sempred(ast) {
return [new SemPred(this, ast)];
}
ruleRef(id, label, args) {
const invokeOp = new InvokeRule(this, id, label);
if (this.controller.needsImplicitLabel(id, invokeOp)) {
this.defineImplicitLabel(id, invokeOp);
}
const listLabelOp = this.getAddToListOpIfListLabelPresent(invokeOp, label);
return [invokeOp, listLabelOp];
}
getCurrentRuleFunction() {
return this.controller.currentRuleFunction;
}
tokenRef(id, labelAST, args) {
const matchOp = new MatchToken(this, id);
if (labelAST) {
const label = labelAST.getText();
const rf = this.getCurrentRuleFunction();
if (labelAST.parent?.getType() === ANTLRv4Parser.PLUS_ASSIGN) {
this.defineImplicitLabel(id, matchOp);
const l = this.getTokenListLabelDecl(label);
rf.addContextDecl(id.getAltLabel(), l);
} else {
const d = this.getTokenLabelDecl(label);
matchOp.labels.push(d);
rf.addContextDecl(id.getAltLabel(), d);
}
}
if (this.controller.needsImplicitLabel(id, matchOp)) {
this.defineImplicitLabel(id, matchOp);
}
const listLabelOp = this.getAddToListOpIfListLabelPresent(matchOp, labelAST);
return [matchOp, listLabelOp];
}
getTokenLabelDecl(label) {
return new TokenDecl(this, label);
}
getTokenListLabelDecl(label) {
return new TokenListDecl(this, this.gen.target.getListLabel(label));
}
set(setAST, labelAST, invert) {
let matchOp;
if (invert) {
matchOp = new MatchNotSet(this, setAST);
} else {
matchOp = new MatchSet(this, setAST);
}
if (labelAST !== null) {
const label = labelAST.getText();
const rf = this.getCurrentRuleFunction();
if (labelAST.parent?.getType() === ANTLRv4Parser.PLUS_ASSIGN) {
this.defineImplicitLabel(setAST, matchOp);
const l = this.getTokenListLabelDecl(label);
rf.addContextDecl(setAST.getAltLabel(), l);
} else {
const d = this.getTokenLabelDecl(label);
matchOp.labels.push(d);
rf.addContextDecl(setAST.getAltLabel(), d);
}
}
if (this.controller.needsImplicitLabel(setAST, matchOp)) {
this.defineImplicitLabel(setAST, matchOp);
}
const listLabelOp = this.getAddToListOpIfListLabelPresent(matchOp, labelAST);
return [matchOp, listLabelOp];
}
wildcard(ast, labelAST) {
const wild = new Wildcard(this, ast);
if (labelAST) {
const label = labelAST.getText();
const d = this.getTokenLabelDecl(label);
wild.labels.push(d);
this.getCurrentRuleFunction().addContextDecl(ast.getAltLabel(), d);
if (labelAST.parent?.getType() === ANTLRv4Parser.PLUS_ASSIGN) {
const l = this.getTokenListLabelDecl(label);
this.getCurrentRuleFunction().addContextDecl(ast.getAltLabel(), l);
}
}
if (this.controller.needsImplicitLabel(ast, wild)) {
this.defineImplicitLabel(ast, wild);
}
const listLabelOp = this.getAddToListOpIfListLabelPresent(wild, labelAST);
return [wild, listLabelOp];
}
getChoiceBlock(blkAST, alts, labelAST) {
const decision = blkAST.atnState.decision;
let c;
if (!this.forceAtn && disjoint(this.g.decisionLookahead[decision])) {
c = this.getLL1ChoiceBlock(blkAST, alts);
} else {
c = this.getComplexChoiceBlock(blkAST, alts);
}
if (labelAST) {
const label = labelAST.getText();
const d = this.getTokenLabelDecl(label);
c.label = d;
this.getCurrentRuleFunction().addContextDecl(labelAST.getAltLabel(), d);
if (labelAST.parent?.getType() === ANTLRv4Parser.PLUS_ASSIGN) {
const listLabel = this.gen.target.getListLabel(label);
const l = new TokenListDecl(this, listLabel);
this.getCurrentRuleFunction().addContextDecl(labelAST.getAltLabel(), l);
}
}
return c;
}
getEBNFBlock(ebnfRoot, alts) {
if (!this.forceAtn) {
let decision;
if (ebnfRoot.getType() === ANTLRv4Parser.POSITIVE_CLOSURE) {
decision = ebnfRoot.atnState.decision;
} else if (ebnfRoot.getType() === ANTLRv4Parser.CLOSURE) {
decision = ebnfRoot.atnState.decision;
} else {
decision = ebnfRoot.atnState.decision;
}
if (disjoint(this.g.decisionLookahead[decision])) {
return this.getLL1EBNFBlock(ebnfRoot, alts);
}
}
return this.getComplexEBNFBlock(ebnfRoot, alts);
}
getLL1ChoiceBlock(blkAST, alts) {
return new LL1AltBlock(this, blkAST, alts);
}
getComplexChoiceBlock(blkAST, alts) {
return new AltBlock(this, blkAST, alts);
}
getLL1EBNFBlock(ebnfRoot, alts) {
const ebnf = ebnfRoot.getType();
let c;
switch (ebnf) {
case ANTLRv4Parser.OPTIONAL: {
if (alts.length === 1) {
c = new LL1OptionalBlockSingleAlt(this, ebnfRoot, alts);
} else {
c = new LL1OptionalBlock(this, ebnfRoot, alts);
}
break;
}
case ANTLRv4Parser.CLOSURE: {
if (alts.length === 1) {
c = new LL1StarBlockSingleAlt(this, ebnfRoot, alts);
} else {
c = this.getComplexEBNFBlock(ebnfRoot, alts);
}
break;
}
case ANTLRv4Parser.POSITIVE_CLOSURE: {
if (alts.length === 1) {
c = new LL1PlusBlockSingleAlt(this, ebnfRoot, alts);
} else {
c = this.getComplexEBNFBlock(ebnfRoot, alts);
}
break;
}
default:
}
return c;
}
getComplexEBNFBlock(ebnfRoot, alts) {
const ebnf = ebnfRoot.getType();
let c;
switch (ebnf) {
case ANTLRv4Parser.OPTIONAL: {
c = new OptionalBlock(this, ebnfRoot, alts);
break;
}
case ANTLRv4Parser.CLOSURE: {
c = new StarBlock(this, ebnfRoot, alts);
break;
}
case ANTLRv4Parser.POSITIVE_CLOSURE: {
c = new PlusBlock(this, ebnfRoot, alts);
break;
}
default:
}
return c;
}
getLL1Test(look, blkAST) {
return [new TestSetInline(this, blkAST, look, this.gen.target.getInlineTestSetWordSize())];
}
getGenerator() {
return this.gen;
}
getCurrentOuterMostAlt() {
return this.controller.currentOuterMostAlt;
}
getCurrentBlock() {
return this.controller.currentBlock;
}
rulePostamble(ruleFunction, r) {
if (r.namedActions.has("after") || r.namedActions.has("finally")) {
const gen = this.getGenerator();
const codegenTemplates = gen.templates;
const setStopTokenAST = codegenTemplates.getInstanceOf("recRuleSetStopToken");
const setStopTokenAction = new Action(this, ruleFunction.ruleCtx, setStopTokenAST);
const ops = new Array(1);
ops.push(setStopTokenAction);
return ops;
}
return void 0;
}
needsImplicitLabel(id, op) {
const currentOuterMostAlt = this.getCurrentOuterMostAlt();
const actionRefsAsToken = currentOuterMostAlt.tokenRefsInActions.has(id.getText());
const actionRefsAsRule = currentOuterMostAlt.ruleRefsInActions.has(id.getText());
return op.labels.length === 0 && (actionRefsAsToken || actionRefsAsRule);
}
defineImplicitLabel(ast, op) {
let d;
if (ast.getType() === ANTLRv4Parser.SET || ast.getType() === ANTLRv4Parser.WILDCARD) {
const implLabel = this.gen.target.getImplicitSetLabel(String(ast.token.tokenIndex));
d = this.getTokenLabelDecl(implLabel);
d.isImplicit = true;
} else if (ast.getType() === ANTLRv4Parser.RULE_REF) {
const r = this.g.getRule(ast.getText());
const implLabel = this.gen.target.getImplicitRuleLabel(ast.getText());
const ctxName = this.gen.target.getRuleFunctionContextStructName(r);
d = new RuleContextDecl(this, implLabel, ctxName);
d.isImplicit = true;
} else {
const implLabel = this.gen.target.getImplicitTokenLabel(ast.getText());
d = this.getTokenLabelDecl(implLabel);
d.isImplicit = true;
}
op.labels.push(d);
this.getCurrentRuleFunction().addContextDecl(ast.getAltLabel(), d);
}
getAddToListOpIfListLabelPresent(op, label) {
let labelOp = null;
if (label?.parent?.getType() === ANTLRv4Parser.PLUS_ASSIGN) {
const target = this.gen.target;
const listLabel = target.getListLabel(label.getText());
const listRuntimeName = target.escapeIfNeeded(listLabel);
labelOp = new AddToLabelList(this, listRuntimeName, op.labels[0]);
}
return labelOp;
}
}
export {
ParserFactory
};