public override Choice GetEBNFBlock(GrammarAST ebnfRoot, IList <CodeBlockForAlt> alts) { if (!g.tool.force_atn) { int decision; if (ebnfRoot.Type == ANTLRParser.POSITIVE_CLOSURE) { decision = ((PlusLoopbackState)ebnfRoot.atnState).decision; } else if (ebnfRoot.Type == ANTLRParser.CLOSURE) { decision = ((StarLoopEntryState)ebnfRoot.atnState).decision; } else { decision = ((DecisionState)ebnfRoot.atnState).decision; } if (AnalysisPipeline.Disjoint(g.decisionLOOK[decision])) { return(GetLL1EBNFBlock(ebnfRoot, alts)); } } return(GetComplexEBNFBlock(ebnfRoot, alts)); }
/** In case of option id={...}, set resolve in case they use $foo */ private void SetActionResolver(GrammarAST valueAST) { if (valueAST is ActionAST) { ((ActionAST)valueAST).resolver = currentRule.alt[currentOuterAltNumber]; } }
private void HandleRewriteAtomStart(GrammarAST start) { Rule r = grammar.GetRule(currentRuleName); var tokenRefsInAlt = r.GetTokenRefsInAlt(outerAltNum); bool imaginary = start.Type == TOKEN_REF && !tokenRefsInAlt.Contains(start.Text); if (!imaginary && grammar.BuildAST) { switch (start.Type) { case RULE_REF: case LABEL: case TOKEN_REF: case CHAR_LITERAL: case STRING_LITERAL: // track per block and for entire rewrite rule if (currentRewriteBlock != null) { currentRewriteBlock.rewriteRefsShallow.Add(start); currentRewriteBlock.rewriteRefsDeep.Add(start); } //System.out.println("adding "+$start.Text+" to "+currentRewriteRule.Text); currentRewriteRule.rewriteRefsDeep.Add(start); break; default: break; } } }
// TODO: this strips the tree properly, but since text() // uses the start of stop token index and gets text from that // ineffectively ignores this routine. public virtual GrammarAST StripLeftRecursion(GrammarAST altAST) { GrammarAST lrlabel = null; GrammarAST first = (GrammarAST)altAST.GetChild(0); int leftRecurRuleIndex = 0; if (first.Type == ELEMENT_OPTIONS) { first = (GrammarAST)altAST.GetChild(1); leftRecurRuleIndex = 1; } ITree rref = first.GetChild(1); // if label=rule if ((first.Type == RULE_REF && first.Text.Equals(ruleName)) || (rref != null && rref.Type == RULE_REF && rref.Text.Equals(ruleName))) { if (first.Type == ASSIGN || first.Type == PLUS_ASSIGN) { lrlabel = (GrammarAST)first.GetChild(0); } // remove rule ref (first child unless options present) altAST.DeleteChild(leftRecurRuleIndex); // reset index so it prints properly (sets token range of // ALT to start to right of left recur rule we deleted) GrammarAST newFirstChild = (GrammarAST)altAST.GetChild(leftRecurRuleIndex); altAST.TokenStartIndex = newFirstChild.TokenStartIndex; } return(lrlabel); }
protected virtual GrammarAST ExpandOptionalQuantifiersForAlt(GrammarAST alt) { if (alt.ChildCount == 0) { return(null); } if (alt.GetChild(0).Type == ANTLRParser.OPTIONAL) { GrammarAST root = (GrammarAST)adaptor.Nil(); GrammarAST alt2 = alt.DupTree(); alt2.DeleteChild(0); if (alt2.ChildCount == 0) { adaptor.AddChild(alt2, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } alt.SetChild(0, alt.GetChild(0).GetChild(0)); if (alt.GetChild(0).Type == ANTLRParser.BLOCK && alt.GetChild(0).ChildCount == 1 && alt.GetChild(0).GetChild(0).Type == ANTLRParser.ALT) { GrammarAST list = (GrammarAST)adaptor.Nil(); foreach (object tree in ((GrammarAST)alt.GetChild(0).GetChild(0)).Children) { adaptor.AddChild(list, tree); } adaptor.ReplaceChildren(alt, 0, 0, list); } adaptor.AddChild(root, alt); adaptor.AddChild(root, alt2); return(root); } else if (alt.GetChild(0).Type == ANTLRParser.CLOSURE) { GrammarAST root = (GrammarAST)adaptor.Nil(); GrammarAST alt2 = alt.DupTree(); alt2.DeleteChild(0); if (alt2.ChildCount == 0) { adaptor.AddChild(alt2, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } PlusBlockAST plusBlockAST = new PlusBlockAST(ANTLRParser.POSITIVE_CLOSURE, adaptor.CreateToken(ANTLRParser.POSITIVE_CLOSURE, "+"), null); for (int i = 0; i < alt.GetChild(0).ChildCount; i++) { plusBlockAST.AddChild(alt.GetChild(0).GetChild(i)); } alt.SetChild(0, plusBlockAST); adaptor.AddChild(root, alt); adaptor.AddChild(root, alt2); return(root); } return(alt); }
internal int TestBlockAsSet(GrammarAST t) { Rule r = grammar.GetLocallyDefinedRule(currentRuleName); if (r.HasRewrite(outerAltNum)) { return(-1); } TreeToNFAConverter other = new TreeToNFAConverter(grammar, nfa, factory, new CommonTreeNodeStream(t)); other.state.backtracking++; other.currentRuleName = currentRuleName; other.outerAltNum = outerAltNum; other.blockLevel = blockLevel; var result = other.testBlockAsSet(); if (other.state.failed) { return(-1); } return(result); }
public override void BinaryAlt(AltAST originalAltTree, int alt) { AltAST altTree = (AltAST)originalAltTree.DupTree(); string altLabel = altTree.altLabel != null ? altTree.altLabel.Text : null; string label = null; bool isListLabel = false; GrammarAST lrlabel = StripLeftRecursion(altTree); if (lrlabel != null) { label = lrlabel.Text; isListLabel = lrlabel.Parent.Type == PLUS_ASSIGN; leftRecursiveRuleRefLabels.Add(Tuple.Create(lrlabel, altLabel)); } StripAltLabel(altTree); // rewrite e to be e_[rec_arg] int nextPrec = NextPrecedence(alt); altTree = AddPrecedenceArgToRules(altTree, nextPrec); StripAltLabel(altTree); string altText = Text(altTree); altText = altText.Trim(); LeftRecursiveRuleAltInfo a = new LeftRecursiveRuleAltInfo(alt, altText, label, altLabel, isListLabel, originalAltTree); a.nextPrec = nextPrec; binaryAlts[alt] = a; //System.out.println("binaryAlt " + alt + ": " + altText + ", rewrite=" + rewriteText); }
public override Handle LexerCommand(GrammarAST ID) { ILexerAction lexerAction = CreateLexerAction(ID, null); if (lexerAction != null) { return(Action(ID, lexerAction)); } if (codegenTemplates == null) { // suppress reporting a single missing template when the target couldn't be loaded return(Epsilon(ID)); } // fall back to standard action generation for the command Template cmdST = codegenTemplates.GetInstanceOf("Lexer" + CharSupport.Capitalize(ID.Text) + "Command"); if (cmdST == null) { g.tool.errMgr.GrammarError(ErrorType.INVALID_LEXER_COMMAND, g.fileName, ID.Token, ID.Text); return(Epsilon(ID)); } if (cmdST.impl.FormalArguments != null && cmdST.impl.FormalArguments.Any(x => x.Name == "arg")) { g.tool.errMgr.GrammarError(ErrorType.MISSING_LEXER_COMMAND_ARGUMENT, g.fileName, ID.Token, ID.Text); return(Epsilon(ID)); } return(Action(cmdST.Render())); }
protected virtual bool CheckRange(GrammarAST leftNode, GrammarAST rightNode, int leftValue, int rightValue) { bool result = true; if (leftValue == -1) { result = false; g.tool.errMgr.GrammarError(ErrorType.INVALID_LITERAL_IN_LEXER_SET, g.fileName, leftNode.Token, leftNode.Text); } if (rightValue == -1) { result = false; g.tool.errMgr.GrammarError(ErrorType.INVALID_LITERAL_IN_LEXER_SET, g.fileName, rightNode.Token, rightNode.Text); } if (!result) { return(result); } if (rightValue < leftValue) { g.tool.errMgr.GrammarError(ErrorType.EMPTY_STRINGS_AND_SETS_NOT_ALLOWED, g.fileName, ((GrammarAST)leftNode.Parent).Token, leftNode.Text + ".." + rightNode.Text); } return(result); }
public virtual void CheckForQualifiedRuleIssues(Grammar g, IList <GrammarAST> qualifiedRuleRefs) { foreach (GrammarAST dot in qualifiedRuleRefs) { GrammarAST grammar = (GrammarAST)dot.GetChild(0); GrammarAST rule = (GrammarAST)dot.GetChild(1); g.tool.Log("semantics", grammar.Text + "." + rule.Text); Grammar @delegate = g.GetImportedGrammar(grammar.Text); if (@delegate == null) { errMgr.GrammarError(ErrorType.NO_SUCH_GRAMMAR_SCOPE, g.fileName, grammar.Token, grammar.Text, rule.Text); } else { if (g.GetRule(grammar.Text, rule.Text) == null) { errMgr.GrammarError(ErrorType.NO_SUCH_RULE_IN_SCOPE, g.fileName, rule.Token, grammar.Text, rule.Text); } } } }
public virtual Handle _RuleRef([NotNull] GrammarAST node) { Rule r = g.GetRule(node.Text); if (r == null) { g.tool.errMgr.GrammarError(ErrorType.INTERNAL_ERROR, g.fileName, node.Token, "Rule " + node.Text + " undefined"); return(null); } RuleStartState start = atn.ruleToStartState[r.index]; ATNState left = NewState(node); ATNState right = NewState(node); int precedence = 0; if (((GrammarASTWithOptions)node).GetOptionString(LeftRecursiveRuleTransformer.PRECEDENCE_OPTION_NAME) != null) { precedence = int.Parse(((GrammarASTWithOptions)node).GetOptionString(LeftRecursiveRuleTransformer.PRECEDENCE_OPTION_NAME)); } RuleTransition call = new RuleTransition(start, r.index, precedence, right); left.AddTransition(call); node.atnState = left; return(new Handle(left, right)); }
public virtual void CheckForLabelConflict(Rule r, GrammarAST labelID) { string name = labelID.Text; if (nameToRuleMap.ContainsKey(name)) { ErrorType etype = ErrorType.LABEL_CONFLICTS_WITH_RULE; errMgr.GrammarError(etype, g.fileName, labelID.Token, name, r.name); } if (tokenIDs.Contains(name)) { ErrorType etype = ErrorType.LABEL_CONFLICTS_WITH_TOKEN; errMgr.GrammarError(etype, g.fileName, labelID.Token, name, r.name); } if (r.args != null && r.args.Get(name) != null) { ErrorType etype = ErrorType.LABEL_CONFLICTS_WITH_ARG; errMgr.GrammarError(etype, g.fileName, labelID.Token, name, r.name); } if (r.retvals != null && r.retvals.Get(name) != null) { ErrorType etype = ErrorType.LABEL_CONFLICTS_WITH_RETVAL; errMgr.GrammarError(etype, g.fileName, labelID.Token, name, r.name); } if (r.locals != null && r.locals.Get(name) != null) { ErrorType etype = ErrorType.LABEL_CONFLICTS_WITH_LOCAL; errMgr.GrammarError(etype, g.fileName, labelID.Token, name, r.name); } }
// support public virtual void DefineImplicitLabel(GrammarAST ast, LabeledOp op) { Decl d; if (ast.Type == ANTLRParser.SET || ast.Type == ANTLRParser.WILDCARD) { string implLabel = GetTarget().GetImplicitSetLabel(ast.Token.TokenIndex.ToString()); d = GetTokenLabelDecl(implLabel); ((TokenDecl)d).isImplicit = true; } else if (ast.Type == ANTLRParser.RULE_REF) { // a rule reference? Rule r = g.GetRule(ast.Text); string implLabel = GetTarget().GetImplicitRuleLabel(ast.Text); string ctxName = GetTarget().GetRuleFunctionContextStructName(r); d = new RuleContextDecl(this, implLabel, ctxName); ((RuleContextDecl)d).isImplicit = true; } else { string implLabel = GetTarget().GetImplicitTokenLabel(ast.Text); d = GetTokenLabelDecl(implLabel); ((TokenDecl)d).isImplicit = true; } op.GetLabels().Add(d); // all labels must be in scope struct in case we exec action out of context GetCurrentRuleFunction().AddContextDecl(ast.GetAltLabel(), d); }
public override Choice GetComplexEBNFBlock(GrammarAST ebnfRoot, IList <CodeBlockForAlt> alts) { int ebnf = 0; if (ebnfRoot != null) { ebnf = ebnfRoot.Type; } Choice c = null; switch (ebnf) { case ANTLRParser.OPTIONAL: c = new OptionalBlock(this, ebnfRoot, alts); break; case ANTLRParser.CLOSURE: c = new StarBlock(this, ebnfRoot, alts); break; case ANTLRParser.POSITIVE_CLOSURE: c = new PlusBlock(this, ebnfRoot, alts); break; } return(c); }
private void HandleRule(GrammarAST start, StateCluster g, GrammarAST blockStart, GrammarAST id) { if (blockStart.SetValue != null) { // if block comes back as a set not BLOCK, make it // a single ALT block g = factory.BuildAlternativeBlockFromSet(g); } if (Rule.GetRuleType(currentRuleName) == RuleType.Parser || grammar.type == GrammarType.Lexer) { // attach start node to block for this rule Rule thisR = grammar.GetLocallyDefinedRule(currentRuleName); NFAState start2 = thisR.StartState; start2.associatedASTNode = id; start2.AddTransition(new Transition(Label.EPSILON, g.Left)); // track decision if > 1 alts if (grammar.GetNumberOfAltsForDecisionNFA(g.Left) > 1) { g.Left.Description = grammar.GrammarTreeToString(start, false); g.Left.SetDecisionASTNode(blockStart); int d = grammar.AssignDecisionNumber(g.Left); grammar.SetDecisionNFA(d, g.Left); grammar.SetDecisionBlockAST(d, blockStart); } // hook to end of rule node NFAState end = thisR.StopState; g.Right.AddTransition(new Transition(Label.EPSILON, end)); } }
public virtual IntervalSet GetSetFromCharSetLiteral(GrammarAST charSetAST) { string chars = charSetAST.Text; chars = chars.Substring(1, chars.Length - 2); string cset = '"' + chars + '"'; IntervalSet set = new IntervalSet(); if (chars.Length == 0) { g.tool.errMgr.GrammarError(ErrorType.EMPTY_STRINGS_AND_SETS_NOT_ALLOWED, g.fileName, charSetAST.Token, "[]"); return(set); } // unescape all valid escape char like \n, leaving escaped dashes as '\-' // so we can avoid seeing them as '-' range ops. chars = CharSupport.GetStringFromGrammarStringLiteral(cset); if (chars == null) { g.tool.errMgr.GrammarError(ErrorType.INVALID_ESCAPE_SEQUENCE, g.fileName, charSetAST.Token); return(set); } int n = chars.Length; // now make x-y become set of char for (int i = 0; i < n; i++) { int c = chars[i]; if (c == '\\' && (i + 1) < n && chars[i + 1] == '-') { // \- CheckSetCollision(charSetAST, set, '-'); set.Add('-'); i++; } else if ((i + 2) < n && chars[i + 1] == '-') { // range x-y int x = c; int y = chars[i + 2]; if (x <= y) { CheckSetCollision(charSetAST, set, x, y); set.Add(x, y); } else { g.tool.errMgr.GrammarError(ErrorType.EMPTY_STRINGS_AND_SETS_NOT_ALLOWED, g.fileName, charSetAST.Token, "[" + (char)x + "-" + (char)y + "]"); } i += 2; } else { CheckSetCollision(charSetAST, set, c); set.Add(c); } } return(set); }
private StateCluster HandleTreeFirstElement(GrammarAST firstElementStart, StateCluster element, out StateCluster down) { down = factory.BuildAtom(Label.DOWN, firstElementStart); // TODO set following states for imaginary nodes? //el.followingNFAState = down.Right; return factory.BuildAB(element, down); }
public Choice(OutputModelFactory factory, GrammarAST blkOrEbnfRootAST, IList <CodeBlockForAlt> alts) : base(factory, blkOrEbnfRootAST) { this.alts = alts; }
public virtual void BuildNormalRuleFunction(Rule r, RuleFunction function) { CodeGenerator gen = @delegate.GetGenerator(); // TRIGGER factory functions for rule alts, elements GrammarASTAdaptor adaptor = new GrammarASTAdaptor(r.ast.Token.InputStream); GrammarAST blk = (GrammarAST)r.ast.GetFirstChildWithType(ANTLRParser.BLOCK); CommonTreeNodeStream nodes = new CommonTreeNodeStream(adaptor, blk); walker = new SourceGenTriggers(nodes, this); try { // walk AST of rule alts/elements function.code = DefaultOutputModelFactory.List(walker.block(null, null)); function.hasLookaheadBlock = walker.hasLookaheadBlock; } catch (Antlr.Runtime.RecognitionException e) { @delegate.GetGenerator().tool.ConsoleError.WriteLine(e.Message); @delegate.GetGenerator().tool.ConsoleError.WriteLine(e.StackTrace); } function.ctxType = @delegate.GetTarget().GetRuleFunctionContextStructName(function); function.postamble = RulePostamble(function, r); }
private StateCluster HandleEbnfPositiveClosureBlock(GrammarAST start, GrammarAST blk, StateCluster bg) { GrammarAST eob = blk.LastChild; if (blk.SetValue != null) { bg = factory.BuildAlternativeBlockFromSet(bg); } StateCluster g = factory.BuildAplus(bg); // don't make a decision on left edge, can reuse loop end decision // track the loop back / exit decision point bg.Right.Description = "()+ loopback of " + grammar.GrammarTreeToString(start, false); int d = grammar.AssignDecisionNumber(bg.Right); grammar.SetDecisionNFA(d, bg.Right); grammar.SetDecisionBlockAST(d, blk); bg.Right.SetDecisionASTNode(eob); // make block entry state also have same decision for interpreting grammar NFAState altBlockState = (NFAState)g.Left.GetTransition(0).Target; altBlockState.SetDecisionASTNode(start); altBlockState.DecisionNumber = d; return(g); }
public override void SuffixAlt(AltAST originalAltTree, int alt) { AltAST altTree = (AltAST)originalAltTree.DupTree(); string altLabel = altTree.altLabel != null ? altTree.altLabel.Text : null; string label = null; bool isListLabel = false; GrammarAST lrlabel = StripLeftRecursion(altTree); if (lrlabel != null) { label = lrlabel.Text; isListLabel = lrlabel.Parent.Type == PLUS_ASSIGN; leftRecursiveRuleRefLabels.Add(Tuple.Create(lrlabel, altLabel)); } StripAltLabel(altTree); string altText = Text(altTree); altText = altText.Trim(); LeftRecursiveRuleAltInfo a = new LeftRecursiveRuleAltInfo(alt, altText, label, altLabel, isListLabel, originalAltTree); suffixAlts[alt] = a; // System.out.println("suffixAlt " + alt + ": " + altText + ", rewrite=" + rewriteText); }
private StateCluster HandleNotAtomCharLiteral(GrammarAST notNode, GrammarAST charLiteral) { int ttype = 0; if (grammar.type == GrammarType.Lexer) { ttype = Grammar.GetCharValueFromGrammarCharLiteral(charLiteral.Text); } else { ttype = grammar.GetTokenType(charLiteral.Text); } IIntSet notAtom = grammar.Complement(ttype); if (notAtom.IsNil) { ErrorManager.GrammarError( ErrorManager.MSG_EMPTY_COMPLEMENT, grammar, charLiteral.Token, charLiteral.Text); } return(factory.BuildSet(notAtom, notNode)); }
/** * Get {@code #} labels. The keys of the map are the labels applied to outer * alternatives of a lexer rule, and the values are collections of pairs * (alternative number and {@link AltAST}) identifying the alternatives with * this label. Unlabeled alternatives are not included in the result. */ public virtual IDictionary <string, IList <System.Tuple <int, AltAST> > > GetAltLabels() { IDictionary <string, IList <System.Tuple <int, AltAST> > > labels = new LinkedHashMap <string, IList <System.Tuple <int, AltAST> > >(); for (int i = 1; i <= numberOfAlts; i++) { GrammarAST altLabel = alt[i].ast.altLabel; if (altLabel != null) { IList <System.Tuple <int, AltAST> > list; if (!labels.TryGetValue(altLabel.Text, out list) || list == null) { list = new List <System.Tuple <int, AltAST> >(); labels[altLabel.Text] = list; } list.Add(Tuple.Create(i, alt[i].ast)); } } if (labels.Count == 0) { return(null); } return(labels); }
private void HandleSetElementTokenReference(IIntSet elements, GrammarAST t) { int ttype; if (grammar.type == GrammarType.Lexer) { // recursively will invoke this rule to match elements in target rule ref IIntSet ruleSet = grammar.GetSetFromRule(this, t.Text); if (ruleSet == null) { ErrorManager.GrammarError(ErrorManager.MSG_RULE_INVALID_SET, grammar, t.Token, t.Text); } else { elements.AddAll(ruleSet); } } else { ttype = grammar.GetTokenType(t.Text); if (elements.Contains(ttype)) { ErrorManager.GrammarError(ErrorManager.MSG_DUPLICATE_SET_ENTRY, grammar, t.Token, t.Text); } elements.Add(ttype); } }
public override void RuleCatch(GrammarAST arg, ActionAST action) { GrammarAST catchme = (GrammarAST)action.Parent; currentRule.exceptions.Add(catchme); action.resolver = currentRule; }
private ANTLRTreePrinter.block_return Block(GrammarAST t, bool forceParens) { ANTLRTreePrinter other = new ANTLRTreePrinter(new CommonTreeNodeStream(t)); other.buf = buf; return(other.block(forceParens)); }
private void HandleRuleAction(Rule r, GrammarAST amp, GrammarAST id, GrammarAST action) { if (r != null) { r.DefineNamedAction(amp, id, action); } }
private bool HasElementOptions(GrammarAST node) { if (node == null) throw new ArgumentNullException("node"); return node.terminalOptions != null && node.terminalOptions.Count > 0; }
/** Remove any lexer rules from a COMBINED; already passed to lexer */ protected void TrimGrammar() { if (grammar.type != GrammarType.Combined) { return; } // form is (header ... ) ( grammar ID (scope ...) ... ( rule ... ) ( rule ... ) ... ) GrammarAST p = root; // find the grammar spec while (!p.Text.Equals("grammar")) { p = (GrammarAST)p.Parent.GetChild(p.ChildIndex + 1); } for (int i = 0; i < p.ChildCount; i++) { if (p.GetChild(i).Type != RULE) { continue; } string ruleName = p.GetChild(i).GetChild(0).Text; //Console.Out.WriteLine( "rule " + ruleName + " prev=" + prev.getText() ); if (Rule.GetRuleType(ruleName) == RuleType.Lexer) { // remove lexer rule p.DeleteChild(i); i--; } } //Console.Out.WriteLine( "root after removal is: " + root.ToStringList() ); }
public override IList <SrcOp> Wildcard(GrammarAST ast, GrammarAST labelAST) { Wildcard wild = new Wildcard(this, ast); // TODO: dup with tokenRef if (labelAST != null) { string label = labelAST.Text; Decl d = GetTokenLabelDecl(label); wild.labels.Add(d); GetCurrentRuleFunction().AddContextDecl(ast.GetAltLabel(), d); if (labelAST.Parent.Type == ANTLRParser.PLUS_ASSIGN) { TokenListDecl l = GetTokenListLabelDecl(label); GetCurrentRuleFunction().AddContextDecl(ast.GetAltLabel(), l); } } if (controller.NeedsImplicitLabel(ast, wild)) { DefineImplicitLabel(ast, wild); } AddToLabelList listLabelOp = GetAddToListOpIfListLabelPresent(wild, labelAST); return(List(wild, listLabelOp)); }