public int DefineTerminal(string name, bool isExplicit, int token, string pattern = null) { if (terminals.ContainsKey(name)) { throw GrammarDefineException.DuplicateTerminalDefinition(name); } terminals.Add(name, new Terminal { Id = id, Token = token, Pattern = pattern, Explicit = isExplicit, }); return(id++); }
public IGrammarParser Build() { var nameToToken = new Dictionary <string, LLnToken>(); var nonTerminalTokens = new List <NonTerminalPair>(roots.Count + nonTerminals.Count); foreach (var kv in terminals) { nameToToken.Add( kv.Key, new TerminalToken( kv.Value.Id, kv.Value.Explicit, kv.Key, kv.Value.Token, kv.Value.Pattern ) ); } foreach (var kv in nonTerminals) { var token = new NonTerminalToken(kv.Key, kv.Value.Count); nameToToken.Add(kv.Key, token); nonTerminalTokens.Add(new NonTerminalPair { Token = token, Paths = kv.Value, }); } foreach (var pair in nonTerminalTokens) { var token = pair.Token; foreach (var path in pair.Paths) { var len = path.Path.Length; var tokens = new LLnToken[len]; for (int i = 0; i < len; i++) { if (!nameToToken.TryGetValue(path.Path[i], out var refToken)) { throw GrammarDefineException.NonTerminalRefTokenNotFound(token.Name, path.Path[i]); } tokens[i] = refToken; } token.AddPath(path.Id, path.Explicit, tokens); } } var rootToken = new RootToken(roots.Count); foreach (var path in roots) { var len = path.Path.Length; var tokens = new LLnToken[len + 1]; for (int i = 0; i < len; i++) { if (!nameToToken.TryGetValue(path.Path[i], out var refToken)) { throw GrammarDefineException.NonTerminalRefTokenNotFound(rootToken.Name, path.Path[i]); } tokens[i] = refToken; } tokens[len] = EOFToken.Instance; rootToken.AddPath(path.Id, false, tokens); } var parser = new LLnParser(rootToken); return(parser); }