private AstNode Factor() { // FACTOR = UNARY-OP FACTOR | // INCREMENT-BY-ONE VARIABLE | // DECREMENT-BY-ONE VARIABLE | // NUMBER (INCREMENT-BY-ONE) | // NUMBER (DECREMENT-BY-ONE) | // STRING | CHAR | BOOLEAN | // PARAM-START EXPRESSION PARAM-END | // VARIABLE var token = _currentToken; if (Tokens.IsUnaryOperator(token.Type)) { Eat(token.Type); return(new UnaryOperationNode(token, Factor())); } else if (token.Type == Tokens.IncrementByOne) { Eat(token.Type); return(new PreIncrementNode(Variable())); } else if (token.Type == Tokens.DecrementByOne) { Eat(token.Type); return(new PreDecrementNode(Variable())); } else if (Tokens.IsNumberType(token.Type)) { return(Number()); } else if (token.Type == Tokens.String) { Eat(token.Type); return(new StringNode((string)token.Value)); } else if (token.Type == Tokens.Character) { Eat(token.Type); return(new CharacterNode((char)token.Value)); } else if (token.Type == Tokens.True) { Eat(token.Type); return(new BooleanNode(true)); } else if (token.Type == Tokens.False) { Eat(token.Type); return(new BooleanNode(false)); } else if (token.Type == Tokens.ParamStart) { Eat(Tokens.ParamStart); var expression = Expression(); Eat(Tokens.ParamEnd); return(expression); } else { var variable = Variable(); if (token.Type == Tokens.IncrementByOne) { Eat(token.Type); return(new PostIncrementNode(variable)); } else if (token.Type == Tokens.DecrementByOne) { Eat(token.Type); return(new PostDecrementNode(variable)); } return(variable); } throw new Exception("Factor bad. Very bad. No like it. Stop."); }