Exemplo n.º 1
0
        public NonTerminal GetNonTerminal(PSMComponent psmComponent)
        {
            NonTerminal nonTerminal;

            if (!NonTermialsDictionary.TryGetValue(psmComponent, out nonTerminal))
            {
                nonTerminal = new NonTerminal(psmComponent);
                if (!Exolutio.SupportingClasses.NameSuggestor <NonTerminal> .IsNameUnique(NonTerminals, nonTerminal.ToString(), n => n.ToString()))
                {
                    string name = Exolutio.SupportingClasses.NameSuggestor <NonTerminal> .SuggestUniqueName(NonTerminals, nonTerminal.ToString(), n => n.ToString(), true, false);

                    nonTerminal.UniqueName = name;
                }
                NonTermialsDictionary[psmComponent] = nonTerminal;
                NonTerminals.Add(nonTerminal);
            }
            return(nonTerminal);
        }
Exemplo n.º 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();
        }