예제 #1
0
 public List <GrammarScriptItem> GetItems(string name, bool includeMatches = false)
 {
     if (!includeMatches)
     {
         List <GrammarScriptItem> list = new List <GrammarScriptItem>();
         if (Terminals.ContainsKey(name))
         {
             list.Add(new GrammarScriptItem(GrammarScriptItemType.Terminal, name));
         }
         else if (Symbols.ContainsKey(name))
         {
             list.Add(new GrammarScriptItem(GrammarScriptItemType.Symbol, name));
         }
         else if (SymbolSets.ContainsKey(name))
         {
             list.Add(new GrammarScriptItem(GrammarScriptItemType.SymbolSet, name));
         }
         return(list);
     }
     else
     {
         List <GrammarScriptItem> list = new List <GrammarScriptItem>();
         foreach (string k in Terminals.Keys)
         {
             if (k.Contains(name))
             {
                 list.Add(new GrammarScriptItem(GrammarScriptItemType.Terminal, k));
             }
         }
         foreach (string k in Symbols.Keys)
         {
             if (k.Contains(name))
             {
                 list.Add(new GrammarScriptItem(GrammarScriptItemType.Symbol, k));
             }
         }
         foreach (string k in Terminals.Keys)
         {
             if (k.Contains(name))
             {
                 list.Add(new GrammarScriptItem(GrammarScriptItemType.Terminal, k));
             }
         }
         return(list);
     }
 }
예제 #2
0
        private void BuildLexerRule(LexerRuleContext lexerRuleContext)
        {
            //TODO: change actionName to delegate.
            string actionName = null;

            if (lexerRuleContext.GrammarName() != null)
            {
                actionName = lexerRuleContext.GrammarName().GetText();
            }

            string name = lexerRuleContext.LexerName().GetText();

            if (Terminals.ContainsKey(name))
            {
                throw new GrammarBuilderException($"Terminal {name} is defined twice");
            }
            var terminal = Terminals[name] = new Terminal(name);

            string regexp = lexerRuleContext.STRING().GetText();

            terminal.LexerRule = new LexerRule(0, regexp, actionName);
        }
예제 #3
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();
        }