public Token GetToken() { State = LexicAnalyserState.Initial; Value = HasNext ? Character.ToString() : ""; Token token = null; while (HasNext && token == null) { switch (State) { case LexicAnalyserState.Initial: HandleInitial(); break; case LexicAnalyserState.NonTerminal: token = new NonTerminalToken(Value); CurrentIndex++; break; case LexicAnalyserState.Space: token = new SpaceToken(); CurrentIndex++; break; case LexicAnalyserState.Terminal: token = new TerminalToken(Value); CurrentIndex++; break; case LexicAnalyserState.Empty: token = new EmptyToken(); CurrentIndex++; break; case LexicAnalyserState.NewLine: token = new NewLineToken(Value); CurrentIndex++; break; case LexicAnalyserState.Identifier: token = new IdentifierToken(Value); CurrentIndex++; break; case LexicAnalyserState.Number: token = new NumberToken(Value); CurrentIndex++; break; case LexicAnalyserState.Var: token = new VarToken(); CurrentIndex++; break; case LexicAnalyserState.Write: token = new WriteToken(); CurrentIndex++; break; case LexicAnalyserState.Read: token = new ReadToken(); CurrentIndex++; break; case LexicAnalyserState.If: token = new IfToken(); CurrentIndex++; break; case LexicAnalyserState.End: token = new EndToken(); CurrentIndex++; break; case LexicAnalyserState.Then: token = new ThenToken(); CurrentIndex++; break; case LexicAnalyserState.Begin: token = new BeginToken(); CurrentIndex++; break; case LexicAnalyserState.While: token = new WhileToken(); CurrentIndex++; break; case LexicAnalyserState.Do: token = new DoToken(); CurrentIndex++; break; case LexicAnalyserState.SemiColon: token = new SemiColonToken(); CurrentIndex++; break; case LexicAnalyserState.OpenParentheses: token = new OpenParenthesesToken(); CurrentIndex++; break; case LexicAnalyserState.CloseParentheses: token = new CloseParenthesesToken(); CurrentIndex++; break; case LexicAnalyserState.Plus: token = new PlusToken(); CurrentIndex++; break; case LexicAnalyserState.Sub: token = new SubToken(); CurrentIndex++; break; case LexicAnalyserState.Great: token = new GreatToken(); CurrentIndex++; break; case LexicAnalyserState.Less: token = new LessToken(); CurrentIndex++; break; case LexicAnalyserState.Equal: token = new EqualToken(); CurrentIndex++; break; case LexicAnalyserState.Repeat: token = new RepeatToken(); CurrentIndex++; break; case LexicAnalyserState.Until: token = new UntilToken(); CurrentIndex++; break; case LexicAnalyserState.Attribution: token = new AttributionToken(); CurrentIndex++; break; case LexicAnalyserState.NotEqual: token = new NotEqualToken(); CurrentIndex++; break; case LexicAnalyserState.GreatOrEqual: token = new GreatOrEqualToken(); CurrentIndex++; break; case LexicAnalyserState.LessOrEqual: token = new LessOrEqualToken(); CurrentIndex++; break; default: throw new ArgumentOutOfRangeException(); } } return(token); }
public INonterminalToken Parse() { ITerminalToken?token = Lexer.Next(stack.StateId); while (token != null) { var action = Decode(token.Symbol.Id); switch (action.Action) { case ParseAction.Error: HandleError(token); token = null; break; case ParseAction.Shift: Shift(action.Number); break; case ParseAction.Reduce: Reduce(action.Number); break; case ParseAction.Accept: Debug.Assert(Lexer.IsEnd()); token = null; break; } } return((INonterminalToken)stack.Pop().Token); void HandleError(ITerminalToken token) { var msg = Errors.GetExpectedMessage(token.Location, Errors.GetSymbols(stack.StateId).ToArray()); throw new ParserException(msg); } void Shift(int stateId) { Debug.Assert(token != null); stack.Push(new StackItem(token, stateId)); token = Lexer.Next(stack.StateId); } void Reduce(int productionId) { var production = Context.Productions[productionId]; var nonterminal = production.Nonterminal; IToken token; var popped = stack.Pop(production.Length); var rhs = production.DropFilter(popped).ToArray(); switch (nonterminal.Repeat) { case RepeatKind.Star: switch (rhs.Length) { case 0: /* empty part */ { token = new RepeatToken(RepeatSymbol.Star); break; } case 1: /* core part */ { var item = rhs[0]; token = new RepeatToken(RepeatSymbol.Star, item); break; } case 2: /* recursive part */ { var item = rhs[1]; var repeat = (RepeatToken)rhs[0]; repeat.Add(item); token = repeat; break; } default: throw new InternalException(); } break; case RepeatKind.Plus: switch (rhs.Length) { case 1: /* core part */ { var item = rhs[0]; token = new RepeatToken(RepeatSymbol.Plus, item); break; } case 2: /* recursive part */ { var item = rhs[1]; var repeat = (RepeatToken)rhs[0]; repeat.Add(item); token = repeat; break; } default: throw new InternalException(); } break; case RepeatKind.Optional: switch (rhs.Length) { case 0: /* empty part */ { token = new RepeatToken(RepeatSymbol.Option); break; } default: /* core part */ { var item = rhs[0]; token = new RepeatToken(RepeatSymbol.Option, rhs); break; } } break; case RepeatKind.None: if (production.IsPromote) { if (rhs.Length != 1) { throw new InternalException(); } token = rhs[0]; } else { token = new NonterminalToken(nonterminal, rhs); } break; default: throw new InternalException(); } var action = Decode(nonterminal.Id); if (action.Action != ParseAction.Shift) { throw new ParserException(); } stack.Push(new StackItem(token, action.Number)); } }