private static void MatchToken(TokenType tokenType, string content, TokenStream tokenStream) { CheckEnd(tokenStream); if (tokenStream.Current.Type == tokenType && tokenStream.Current.Content == content) { tokenStream.Next(); } else { throw new ParserException(String.Format( "Expected '{0}' at position {1}.", content, tokenStream.Current.Start)); } }
private static AstNode LeftAssocCombiner( string[] operators, ParseFunction termParser, TokenStream tokenStream) { AstNode leftTerm = termParser(tokenStream); while (tokenStream.HasMoreTokens && OneOf(tokenStream.Current.Content, operators)) { AstNode tokenNode = new AstNode(AstNodeType.Identifier, tokenStream.Current); tokenStream.Next(); AstNode rightTerm = termParser(tokenStream); leftTerm = new AstNode( AstNodeType.BinaryExpression, new AstNode[] { tokenNode, leftTerm, rightTerm }); } return leftTerm; }
private static AstNode ParseArgumentList(TokenStream tokenStream) { CheckEnd(tokenStream); List<AstNode> arguments = new List<AstNode>(); bool finish = tokenStream.Current.Type == TokenType.CloseParen; while (!finish) { if (tokenStream.Current.Type == TokenType.Identifier) { arguments.Add(new AstNode(AstNodeType.Identifier, tokenStream.Current)); } else { throw new ParserException(string.Format("Expected an identifier at {0}.", tokenStream.Current.Start)); } tokenStream.Next(); CheckEnd(tokenStream); if (tokenStream.Current.Type == TokenType.CloseParen) { finish = true; } else { MatchToken(TokenType.Comma, ",", tokenStream); } } return new AstNode(AstNodeType.ArgumentList, arguments); }
private static AstNode ParseExprUnary(TokenStream tokenStream) { CheckEnd(tokenStream); AstNode result; if (tokenStream.Current.Type == TokenType.OpenParen) { result = ParseParenExpression(tokenStream); } else if (tokenStream.Current.Type == TokenType.Minus || tokenStream.Current.Type == TokenType.LogicalNot) { AstNode tokenNode = new AstNode(AstNodeType.Identifier, tokenStream.Current); tokenStream.Next(); AstNode negatedExpression = ParseExprUnary(tokenStream); result = new AstNode(AstNodeType.UnaryExpression, new AstNode[] { tokenNode, negatedExpression }); } else if (tokenStream.Current.Type == TokenType.Identifier) { AstNode tokenNode = new AstNode(AstNodeType.Identifier, tokenStream.Current); tokenStream.Next(); if (tokenStream.HasMoreTokens && tokenStream.Current.Type == TokenType.OpenParen) { result = ParseFunctionCallExpression(tokenNode, tokenStream); } else { result = tokenNode; } } else if (tokenStream.Current.Type == TokenType.Number) { result = new AstNode(AstNodeType.Number, tokenStream.Current); tokenStream.Next(); } else { throw new ParserException(String.Format( "Expecting an unary expression at {0}.", tokenStream.Current.Start)); } while (tokenStream.HasMoreTokens && tokenStream.Current.Type == TokenType.OpenParen) { result = ParseFunctionCallExpression(result, tokenStream); } return result; }
private static AstNode ParseAssignmentOrFunctionCallStatement(TokenStream tokenStream) { CheckEnd(tokenStream); AstNode tokenNode = new AstNode(AstNodeType.Identifier, tokenStream.Current); tokenStream.Next(); CheckEnd(tokenStream); if (tokenStream.Current.Type == TokenType.Equal) { return ParseAssignmentStatement(tokenNode, tokenStream); } else if (tokenStream.Current.Type == TokenType.OpenParen) { AstNode result = ParseFunctionCallExpression(tokenNode, tokenStream); MatchToken(TokenType.Semicolon, ";", tokenStream); return result; } else { throw new ParserException(String.Format( "Expected an assignment or function call at {0}.", tokenNode.Token.Start)); } }