public AsyncRegexLexer(IAsyncLAIterator <int> charSource, IReadOnlyDictionary <string, RegexTuple[]> patternTable) { _charSource = charSource; _patternTable = patternTable; _states = new Stack <string>(new [] { RootState }); }
public AsyncRegexLexer(IAsyncLAIterator <int> charSource, params RegexTuple[] patterns) : this(charSource, new Dictionary <string, RegexTuple[]> { { RootState, patterns } }) { // calls below }
/// <summary> /// Based on: http://www.goldparser.org/doc/engine-pseudo/parse-Item.htm /// </summary> /// <param name="tokenIterator">Item iterator which will be owned by the caller</param> /// <param name="debugger">Enables debugging support</param> /// <param name="trimReductions">If true (default), trim reductions of the form L -> R, where R is a non-terminal</param> /// <param name="allowRewriting">Apply rewriting functions</param> /// <returns>The reduced program tree on acceptance or the erroneous Item</returns> public async Task <Item> ParseInputAsync(IAsyncLAIterator <Item> tokenIterator, Debug debugger, bool trimReductions = true, bool allowRewriting = true) { const int initState = 0; var tokenStack = new Stack <Item>(); var state = initState; while (true) { var token = await tokenIterator.LookAheadAsync(); var action = ParseTable.Actions[state, token.ID + 1]; debugger.DumpParsingState(state, tokenStack, token, action); switch (action.ActionType) { case ActionType.Shift: state = action.ActionParameter; token.State = state; tokenStack.Push(token); await tokenIterator.MoveNextAsync(); break; case ActionType.Reduce: var nProduction = action.ActionParameter; var production = Productions[nProduction]; var nChildren = production.Right.Length; Item reduction; if (trimReductions && nChildren == 1 && _nonterminals.Contains(production.Right[0])) { reduction = new Item(production.Left, tokenStack.Pop().Content); } else { var children = new Item[nChildren]; for (var i = 0; i < nChildren; i++) { children[nChildren - i - 1] = tokenStack.Pop(); } var rewrite = (allowRewriting ? production.Rewrite(children) : null) ?? new Reduction(nProduction, children); reduction = new Item(production.Left, rewrite); } var lastState = tokenStack.Count > 0 ? tokenStack.Peek().State : initState; state = ParseTable.Actions[lastState, production.Left + 1].ActionParameter; reduction.State = production.Left; tokenStack.Push(reduction); if (tokenStack.Count == 1 && tokenStack.Peek().ID == 0) { return(tokenStack.Pop()); } break; case ActionType.Error: token.State = state < 0 ? state : -state; return(token); case ActionType.ErrorRR: throw new InvalidOperationException("Reduce-Reduce conflict in grammar: " + token); case ActionType.ErrorSR: throw new InvalidOperationException("Shift-Reduce conflict in grammar: " + token); } debugger.Flush(); } }
/// <summary> /// Based on: http://www.goldparser.org/doc/engine-pseudo/parse-token.htm /// </summary> /// <param name="tokenIterator">Token iterator which will be owned by the caller</param> /// <param name="debugger">Enables debugging support</param> /// <param name="trimReductions">If true (default), trim reductions of the form L -> R, where R is a non-terminal</param> /// <param name="allowRewriting">Apply rewriting functions</param> /// <returns>The reduced program tree on acceptance or the erroneous token</returns> public async Task<Token> ParseInputAsync(IAsyncLAIterator<Token> tokenIterator, Debug debugger, bool trimReductions = true, bool allowRewriting = true) { const int initState = 0; var tokenStack = new Stack<Token>(); var state = initState; while (true) { var token = await tokenIterator.LookAheadAsync(); var action = ParseTable.Actions[state, token.ID + 1]; debugger.DumpParsingState(state, tokenStack, token, action); switch (action.ActionType) { case ActionType.Shift: state = action.ActionParameter; token.State = state; tokenStack.Push(token); await tokenIterator.MoveNextAsync(); break; case ActionType.Reduce: var nProduction = action.ActionParameter; var production = Productions[nProduction]; var nChildren = production.Right.Length; Token reduction; if (trimReductions && nChildren == 1 && _nonterminals.Contains(production.Right[0])) { reduction = new Token(production.Left, tokenStack.Pop().Content); } else { var children = new Token[nChildren]; for (var i = 0; i < nChildren; i++) { children[nChildren - i - 1] = tokenStack.Pop(); } var rewrite = (allowRewriting ? production.Rewrite(children) : null) ?? new Reduction(nProduction, children); reduction = new Token(production.Left, rewrite); } var lastState = tokenStack.Count > 0 ? tokenStack.Peek().State : initState; state = ParseTable.Actions[lastState, production.Left + 1].ActionParameter; reduction.State = production.Left; tokenStack.Push(reduction); if (tokenStack.Count == 1 && tokenStack.Peek().ID == 0) { return tokenStack.Pop(); } break; case ActionType.Error: return token; case ActionType.ErrorRR: throw new InvalidOperationException("Reduce-Reduce conflict in grammar: " + token); case ActionType.ErrorSR: throw new InvalidOperationException("Shift-Reduce conflict in grammar: " + token); } debugger.Flush(); } }