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); } } } }
private static void OptimizeSets(Grammar g, ATN atn) { if (g.IsParser()) { // parser codegen doesn't currently support SetTransition return; } int removedStates = 0; IList<DecisionState> decisions = atn.decisionToState; foreach (DecisionState decision in decisions) { if (decision.ruleIndex >= 0) { Rule rule = g.GetRule(decision.ruleIndex); if (char.IsLower(rule.name[0])) { // parser codegen doesn't currently support SetTransition continue; } } IntervalSet setTransitions = new IntervalSet(); for (int i = 0; i < decision.NumberOfTransitions; i++) { Transition epsTransition = decision.Transition(i); if (!(epsTransition is EpsilonTransition)) { continue; } if (epsTransition.target.NumberOfTransitions != 1) { continue; } Transition transition = epsTransition.target.Transition(0); if (!(transition.target is BlockEndState)) { continue; } if (transition is NotSetTransition) { // TODO: not yet implemented continue; } if (transition is AtomTransition || transition is RangeTransition || transition is SetTransition) { setTransitions.Add(i); } } // due to min alt resolution policies, can only collapse sequential alts for (int i = setTransitions.GetIntervals().Count - 1; i >= 0; i--) { Interval interval = setTransitions.GetIntervals()[i]; if (interval.Length <= 1) { continue; } ATNState blockEndState = decision.Transition(interval.a).target.Transition(0).target; IntervalSet matchSet = new IntervalSet(); for (int j = interval.a; j <= interval.b; j++) { Transition matchTransition = decision.Transition(j).target.Transition(0); if (matchTransition is NotSetTransition) { throw new NotImplementedException(); } IntervalSet set = matchTransition.Label; int minElem = set.MinElement; int maxElem = set.MaxElement; for (int k = minElem; k <= maxElem; k++) { if (matchSet.Contains(k)) { char setMin = (char)set.MinElement; char setMax = (char)set.MaxElement; // TODO: Token is missing (i.e. position in source will not be displayed). g.tool.errMgr.GrammarError(ErrorType.CHARACTERS_COLLISION_IN_SET, g.fileName, null, (char)minElem + "-" + (char)maxElem, "[" + setMin + "-" + setMax + "]"); break; } } matchSet.AddAll(set); } Transition newTransition; if (matchSet.GetIntervals().Count == 1) { if (matchSet.Count == 1) { newTransition = new AtomTransition(blockEndState, matchSet.MinElement); } else { Interval matchInterval = matchSet.GetIntervals()[0]; newTransition = new RangeTransition(blockEndState, matchInterval.a, matchInterval.b); } } else { newTransition = new SetTransition(blockEndState, matchSet); } decision.Transition(interval.a).target.SetTransition(0, newTransition); for (int j = interval.a + 1; j <= interval.b; j++) { Transition removed = decision.Transition(interval.a + 1); decision.RemoveTransition(interval.a + 1); atn.RemoveState(removed.target); removedStates++; } } } //System.Console.WriteLine("ATN optimizer removed " + removedStates + " states by collapsing sets."); }
// CAN ONLY CALL THE TWO NEXT METHODS AFTER GRAMMAR HAS RULE DEFS (see semanticpipeline) public virtual void CheckRuleArgs(Grammar g, IList<GrammarAST> rulerefs) { if (rulerefs == null) return; foreach (GrammarAST @ref in rulerefs) { string ruleName = @ref.Text; Rule r = g.GetRule(ruleName); GrammarAST arg = (GrammarAST)@ref.GetFirstChildWithType(ANTLRParser.ARG_ACTION); if (arg != null && (r == null || r.args == null)) { errMgr.GrammarError(ErrorType.RULE_HAS_NO_ARGS, g.fileName, @ref.Token, ruleName); } else if (arg == null && (r != null && r.args != null)) { errMgr.GrammarError(ErrorType.MISSING_RULE_ARGS, g.fileName, @ref.Token, ruleName); } } }
public static IDictionary<Rule, ISet<Rule>> GetRuleDependencies(Grammar g, ICollection<Rule> rules) { IDictionary<Rule, ISet<Rule>> dependencies = new Dictionary<Rule, ISet<Rule>>(); foreach (Rule r in rules) { IList<GrammarAST> tokenRefs = r.ast.GetNodesWithType(ANTLRParser.TOKEN_REF); foreach (GrammarAST tref in tokenRefs) { ISet<Rule> calls; if (!dependencies.TryGetValue(r, out calls) || calls == null) { calls = new HashSet<Rule>(); dependencies[r] = calls; } calls.Add(g.GetRule(tref.Text)); } } return dependencies; }