/// <summary> /// Parses a prototype /// </summary> /// <returns>A prototype syntax tree</returns> private PrototypeSyntaxTree ParsePrototype() { int kind = 0; int binaryPrecedence = 30; string funcName = ""; CharacterToken charToken = null; IdentifierToken identToken = null; switch (this.currentToken.Type) { default: throw new ParserException("Expected function name in prototype"); case TokenType.Identifier: funcName = ((IdentifierToken)this.currentToken).Value; kind = 0; this.NextToken(); //Consume the func name break; case TokenType.Binary: this.NextToken(); charToken = this.currentToken as CharacterToken; if (charToken == null) { throw new ParserException("Expected binary operator"); } funcName = "binary" + charToken.Value; kind = 2; this.NextToken(); //Read the precedence NumberToken numToken = this.currentToken as NumberToken; if (numToken != null) { if (numToken.Value < 1 || numToken.Value > 100) { throw new ParserException("Invalid precedecnce: must be in the range: 1..100"); } binaryPrecedence = (int)numToken.Value; this.NextToken(); } else { throw new ParserException("Expected a number"); } break; case TokenType.Unary: this.NextToken(); charToken = this.currentToken as CharacterToken; if (charToken == null) { throw new ParserException("Expected unary operator"); } funcName = "unary" + charToken.Value; kind = 1; this.NextToken(); break; } charToken = this.currentToken as CharacterToken; if ((charToken != null && charToken.Value != '(') || charToken == null) { throw new ParserException("Expected '(' in prototype"); } //Read the arguments List<string> args = new List<string>(); while (true) { this.NextToken(); identToken = this.currentToken as IdentifierToken; if (identToken != null) { args.Add(identToken.Value); } else { break; } } charToken = this.currentToken as CharacterToken; if ((charToken != null && charToken.Value != ')') || charToken == null) { throw new ParserException("Expected ')' in prototype"); } this.NextToken(); //Consume the ) //Verify the arguments is the same as the operator if (kind != 0 && args.Count != kind) { throw new ParserException("Invalid number of operands for operator"); } return new PrototypeSyntaxTree(funcName, args, kind != 0, binaryPrecedence); }
/// <summary> /// Parses a number expression /// </summary> /// <returns>An number syntax tree</returns> private ExpressionSyntaxTree ParseNumberExpression() { NumberToken numToken = (NumberToken)this.currentToken; this.NextToken(); //Consume the number return new NumberExpressionSyntaxTree(numToken.Value); }