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); }
/// <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(); }