Antlr4.Semantics.BasicSemanticChecks.FinishGrammar C# (CSharp) Method

FinishGrammar() public method

public FinishGrammar ( GrammarRootAST root, GrammarAST ID ) : void
root Antlr4.Tool.Ast.GrammarRootAST
ID Antlr4.Tool.Ast.GrammarAST
return void
        public override void FinishGrammar(GrammarRootAST root, GrammarAST ID)
        {
            Runtime.Misc.MultiMap<string, Rule> baseContexts = new Runtime.Misc.MultiMap<string, Rule>();
            foreach (Rule r in ruleCollector.rules.Values)
            {
                GrammarAST optionAST = r.ast.GetOptionAST("baseContext");

                if (r.ast.IsLexerRule())
                {
                    if (optionAST != null)
                    {
                        IToken errorToken = optionAST.Token;
                        g.tool.errMgr.GrammarError(ErrorType.LEXER_RULE_CANNOT_HAVE_BASE_CONTEXT,
                                                   g.fileName, errorToken, r.name);
                    }

                    continue;
                }

                baseContexts.Map(r.GetBaseContext(), r);

                if (optionAST != null)
                {
                    Rule targetRule;
                    ruleCollector.rules.TryGetValue(r.GetBaseContext(), out targetRule);
                    bool targetSpecifiesBaseContext =
                        targetRule != null
                        && targetRule.ast != null
                        && (targetRule.ast.GetOptionAST("baseContext") != null
                            || !targetRule.name.Equals(targetRule.GetBaseContext()));

                    if (targetSpecifiesBaseContext)
                    {
                        IToken errorToken = optionAST.Token;
                        g.tool.errMgr.GrammarError(ErrorType.BASE_CONTEXT_CANNOT_BE_TRANSITIVE,
                                                   g.fileName, errorToken, r.name);
                    }
                }

                // It's unlikely for this to occur when optionAST is null, but checking
                // anyway means it can detect certain errors within the logic of the
                // Tool itself.
                if (!ruleCollector.rules.ContainsKey(r.GetBaseContext()))
                {
                    IToken errorToken;
                    if (optionAST != null)
                    {
                        errorToken = optionAST.Token;
                    }
                    else
                    {
                        errorToken = ((CommonTree)r.ast.GetChild(0)).Token;
                    }

                    g.tool.errMgr.GrammarError(ErrorType.BASE_CONTEXT_MUST_BE_RULE_NAME,
                                               g.fileName, errorToken, r.name);
                }
            }

            foreach (KeyValuePair<string, IList<Rule>> entry in baseContexts)
            {
                // suppress RULE_WITH_TOO_FEW_ALT_LABELS_GROUP if RULE_WITH_TOO_FEW_ALT_LABELS
                // would already have been reported for at least one rule with this
                // base context.
                bool suppressError = false;
                int altLabelCount = 0;
                int outerAltCount = 0;
                foreach (Rule rule in entry.Value)
                {
                    outerAltCount += rule.numberOfAlts;
                    IList<GrammarAST> altLabels;
                    if (ruleCollector.ruleToAltLabels.TryGetValue(rule.name, out altLabels) && altLabels != null && altLabels.Count > 0)
                    {
                        if (altLabels.Count != rule.numberOfAlts)
                        {
                            suppressError = true;
                            break;
                        }

                        altLabelCount += altLabels.Count;
                    }
                }

                if (suppressError)
                {
                    continue;
                }

                if (altLabelCount != 0 && altLabelCount != outerAltCount)
                {
                    Rule errorRule = entry.Value[0];
                    g.tool.errMgr.GrammarError(ErrorType.RULE_WITH_TOO_FEW_ALT_LABELS_GROUP,
                                               g.fileName, ((CommonTree)errorRule.ast.GetChild(0)).Token, errorRule.name);
                }
            }
        }