Exemple #1
0
        /// <summary>
        /// Build all rules for nonterminal
        /// </summary>
        /// <param name="grammarRuleContext"></param>
        private void BuildGrammarRule(GrammarRuleContext grammarRuleContext)
        {
            string name = grammarRuleContext.grammarName().GetText();

            //save start rule
            if (firstRuleName.Equals(""))
            {
                firstRuleName = name;
            }

            if (NonTerminals.ContainsKey(name))
            {
                throw new GrammarBuilderException($"Nonterminal {name} is defined twice");
            }
            var nonTerminal = NonTerminals[name] = new NonTerminal(name);
            ProductionsContext productions = grammarRuleContext.productions();

            do
            {
                nonTerminal.Productions.Add(BuildProduction(productions.production()));
                productions = productions.productions();
            } while (productions != null);
        }
Exemple #2
0
        /// <summary>
        /// Initialize NonTerminals and Terminals with rules.
        ///
        /// </summary>
        public void Build()
        {
            GrammarFileGrammarLexer  speakLexer        = new GrammarFileGrammarLexer(inputStream);
            CommonTokenStream        commonTokenStream = new CommonTokenStream(speakLexer);
            GrammarFileGrammarParser grammarParser     = new GrammarFileGrammarParser(commonTokenStream);


            foreach (var line in grammarParser.file().line())
            {
                if (line.lexerRule() != null)
                {
                    BuildLexerRule(line.lexerRule());
                }
                else
                {
                    BuildGrammarRule(line.grammarRule());
                }
            }

            InputStartNonTerminal = StartNonTerminal = NonTerminals[firstRuleName];

            if (NonTerminals.ContainsKey("startRule"))
            {
                throw new Exception("The name \"startRule\" is reserved, change the name for this nonterminal");
            }
            NonTerminals.Add("startRule", new NonTerminal("startRule"));
            NonTerminals["startRule"].AddRule(new Production(productionRuleID++, new NonTerminalProduction(firstRuleName)));
            firstRuleName    = "startRule";
            StartNonTerminal = NonTerminals[firstRuleName];

            ///Checking, that we have all terminals and nonterminals, which was mentioned in rules
            foreach (var nonTerminals in NonTerminals.Values)
            {
                foreach (var rule in nonTerminals.Productions)
                {
                    foreach (var element in rule.ProductionElements)
                    {
                        if (element is TerminalProduction)
                        {
                            var e = element as TerminalProduction;
                            if (e.needSetTerminal)
                            {
                                if (!Terminals.ContainsKey(e.Name))
                                {
                                    throw new Exception($"Nonterminal {e} is not defined");
                                }
                                e.Terminal = Terminals[e.Name];
                            }
                        }
                        else if (element is NonTerminalProduction)
                        {
                            var e = element as NonTerminalProduction;
                            if (!NonTerminals.ContainsKey(e.Name))
                            {
                                throw new Exception($"Nonterminal {e} is not defined");
                            }
                            e.NonTerminal = NonTerminals[e.Name];
                        }
                    }
                }
            }

            //Calculate FIRST and FOLLOW for each nonterminal

            //First:
            CalculateFirst();

            //Follow
            CalculateFollow();
        }