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