private void Shift(StackGraph graph, GrammarRuleToken token) { List <Node> resultNodes = new List <Node>(graph.Heads.Count); foreach (var head in graph.Heads) { if (Table[head.State].ShiftActionsMap.TryGetValue(token, out int nextState)) { var newNode = new Node(token, nextState); newNode.PrevNodes.Add(new Edge { PrevNode = head, Meta = new ParseExplanation { ResultToken = token, RuleApplied = null, ChildrenExplained = null } }); resultNodes.Add(newNode); } else if (Table.Grammar.IsSkipGrammar && Table[head.State].ShiftActionsMap.TryGetValue(Table.Grammar.SkipToken, out int skipState)) { var newNode = new Node(token, nextState); newNode.PrevNodes.Add(new Edge { PrevNode = head, Meta = new ParseExplanation { ResultToken = token, RuleApplied = null, ChildrenExplained = null } }); resultNodes.Add(newNode); } } graph.Heads = CombineNodes(resultNodes).ToList(); }
public static Grammar Parse(string grammarAsText) { var lines = grammarAsText .Split(_lineSeparators, StringSplitOptions.RemoveEmptyEntries) .Where(l => !string.IsNullOrWhiteSpace(l)) .Select(l => l.Trim()) .Where(l => !_commentPrefix.Any(prefix => l.StartsWith(prefix))) .ToList(); Dictionary <string, GrammarRuleToken> knownTokens = new Dictionary <string, GrammarRuleToken>(); var skipDefinition = lines[0].Split(_tokenSeparators, StringSplitOptions.RemoveEmptyEntries); bool isSkipGrammar = bool.Parse(skipDefinition[0]); GrammarRuleToken skipToken = isSkipGrammar ? new GrammarRuleToken { IsTerminal = true, Value = skipDefinition[1].Trim() } : null; var acceptingTokens = lines[1].Split(_tokenSeparators, StringSplitOptions.RemoveEmptyEntries).Select(t => ConvertStringToToken(t, knownTokens)).ToList(); var rules = lines.Skip(2).Select((str, index) => ConvertStringToRule(str, index, knownTokens)).ToList(); return(new Grammar { FinalTokens = new HashSet <GrammarRuleToken>(acceptingTokens), Rules = rules, IsSkipGrammar = isSkipGrammar, SkipToken = skipToken }); }
private static GrammarRuleToken ConvertStringToToken(string str, Dictionary <string, GrammarRuleToken> knownTokens) { str = str.Trim(); if (knownTokens.TryGetValue(str, out var existingToken)) { return(existingToken); } var newToken = new GrammarRuleToken { IsTerminal = str.Any(c => char.IsLower(c) || !char.IsUpper(c)), Value = str }; knownTokens.Add(str, newToken); return(newToken); }
public Node(GrammarRuleToken token, int state) { Token = token; State = state; }
public virtual bool Matches(GrammarRuleToken otherToken) { return((IsTerminal == otherToken.IsTerminal) && (Value == otherToken.Value)); }