public override void FinishRule(RuleAST rule, GrammarAST ID, GrammarAST block) { if (rule.IsLexerRule()) return; BlockAST blk = (BlockAST)rule.GetFirstChildWithType(BLOCK); int nalts = blk.ChildCount; GrammarAST idAST = (GrammarAST)rule.GetChild(0); for (int i = 0; i < nalts; i++) { AltAST altAST = (AltAST)blk.GetChild(i); if (altAST.altLabel != null) { string altLabel = altAST.altLabel.Text; // first check that label doesn't conflict with a rule // label X or x can't be rule x. Rule r; if (ruleCollector.rules.TryGetValue(Utils.Decapitalize(altLabel), out r) && r != null) { g.tool.errMgr.GrammarError(ErrorType.ALT_LABEL_CONFLICTS_WITH_RULE, g.fileName, altAST.altLabel.Token, altLabel, r.name); } // Now verify that label X or x doesn't conflict with label // in another rule. altLabelToRuleName has both X and x mapped. string prevRuleForLabel; if (ruleCollector.altLabelToRuleName.TryGetValue(altLabel, out prevRuleForLabel) && prevRuleForLabel != null && !prevRuleForLabel.Equals(rule.GetRuleName())) { g.tool.errMgr.GrammarError(ErrorType.ALT_LABEL_REDEF, g.fileName, altAST.altLabel.Token, altLabel, rule.GetRuleName(), prevRuleForLabel); } } } IList<GrammarAST> altLabels; int numAltLabels = 0; if (ruleCollector.ruleToAltLabels.TryGetValue(rule.GetRuleName(), out altLabels) && altLabels != null) numAltLabels = altLabels.Count; if (numAltLabels > 0 && nalts != numAltLabels) { g.tool.errMgr.GrammarError(ErrorType.RULE_WITH_TOO_FEW_ALT_LABELS, g.fileName, idAST.Token, rule.GetRuleName()); } }