Example #1
0
        private static Node ParseRelationalOp(Parser parser)
        {
            Node left = ParseAddSub(parser);

            if (parser.AcceptToken(TokenType.Operator, ">"))
            {
                return(new BinaryOperationNode(BinaryOperation.GreaterThan, left, ParseRelationalOp(parser)));
            }
            else if (parser.AcceptToken(TokenType.Operator, "<"))
            {
                return(new BinaryOperationNode(BinaryOperation.LessThan, left, ParseRelationalOp(parser)));
            }
            else if (parser.AcceptToken(TokenType.Operator, ">="))
            {
                return(new BinaryOperationNode(BinaryOperation.GreaterOrEqual, left, ParseRelationalOp(parser)));
            }
            else if (parser.AcceptToken(TokenType.Operator, "<="))
            {
                return(new BinaryOperationNode(BinaryOperation.LesserOrEqual, left, ParseRelationalOp(parser)));
            }
            else
            {
                return(left);
            }
        }
        private static AstNode parseAssignment(Parser parser)
        {
            AstNode left = parseAdditive(parser);

            if (parser.AcceptToken(TokenType.Assignment))
                return new BinaryOpNode(BinaryOperation.Assignment, left, parseAssignment(parser));
            else if (parser.AcceptToken(TokenType.Comparison, "=="))
                return new BinaryOpNode(BinaryOperation.Equals, left, parseAssignment(parser));
            else
                return left;
        }
Example #3
0
        private static Node ParseEquals(Parser parser)
        {
            Node left = ParseRelationalOp(parser);

            if (parser.AcceptToken(TokenType.Operator, "=="))
            {
                return(new BinaryOperationNode(BinaryOperation.Equals, left, ParseEquals(parser)));
            }
            else if (parser.AcceptToken(TokenType.Operator, "!="))
            {
                return(new BinaryOperationNode(BinaryOperation.NotEqualTo, left, ParseEquals(parser)));
            }
            else
            {
                return(left);
            }
        }
Example #4
0
        private static Node ParseAddSub(Parser parser)
        {
            Node left = ParseMulDivMod(parser);

            if (parser.AcceptToken(TokenType.Operator, "+"))
            {
                return(new BinaryOperationNode(BinaryOperation.Addition, left, ParseAddSub(parser)));
            }
            else if (parser.AcceptToken(TokenType.Operator, "-"))
            {
                return(new BinaryOperationNode(BinaryOperation.Subtraction, left, ParseAddSub(parser)));
            }
            else
            {
                return(left);
            }
        }
Example #5
0
 public static Node Parse(Parser parser)
 {
     parser.ExpectToken(TokenType.Keyword, "return");
     if (parser.AcceptToken(TokenType.Semicolon))
     {
         return(new ReturnNode(null));
     }
     else
     {
         return(new ReturnNode(ExpressionNode.Parse(parser)));
     }
 }
Example #6
0
        private static Node ParseMulDivMod(Parser parser)
        {
            Node left = ParseFunctionCall(parser);

            if (parser.AcceptToken(TokenType.Operator, "*"))
            {
                return(new BinaryOperationNode(BinaryOperation.Multiplication, left, ParseMulDivMod(parser)));
            }
            else if (parser.AcceptToken(TokenType.Operator, "/"))
            {
                return(new BinaryOperationNode(BinaryOperation.Division, left, ParseMulDivMod(parser)));
            }
            else if (parser.AcceptToken(TokenType.Operator, "%"))
            {
                return(new BinaryOperationNode(BinaryOperation.Modulus, left, ParseMulDivMod(parser)));
            }
            else
            {
                return(left);
            }
        }
Example #7
0
        private static Node ParseAssign(Parser parser)
        {
            Node left = ParseInstanceOf(parser);

            if (parser.AcceptToken(TokenType.Operator, "="))
            {
                return(new BinaryOperationNode(BinaryOperation.Assignment, left, ParseAssign(parser)));
            }
            else if (parser.AcceptToken(TokenType.Operator, "+="))
            {
                return(new BinaryOperationNode(BinaryOperation.Assignment, left, new BinaryOperationNode(BinaryOperation.Addition, left, ParseAssign(parser))));
            }
            else if (parser.AcceptToken(TokenType.Operator, "-="))
            {
                return(new BinaryOperationNode(BinaryOperation.Assignment, left, new BinaryOperationNode(BinaryOperation.Subtraction, left, ParseAssign(parser))));
            }
            else if (parser.AcceptToken(TokenType.Operator, "*="))
            {
                return(new BinaryOperationNode(BinaryOperation.Assignment, left, new BinaryOperationNode(BinaryOperation.Multiplication, left, ParseAssign(parser))));
            }
            else if (parser.AcceptToken(TokenType.Operator, "/="))
            {
                return(new BinaryOperationNode(BinaryOperation.Assignment, left, new BinaryOperationNode(BinaryOperation.Division, left, ParseAssign(parser))));
            }
            else if (parser.AcceptToken(TokenType.Operator, "%="))
            {
                return(new BinaryOperationNode(BinaryOperation.Assignment, left, new BinaryOperationNode(BinaryOperation.Modulus, left, ParseAssign(parser))));
            }
            else
            {
                return(left);
            }
        }
 private static AstNode parseAdditive(Parser parser)
 {
     AstNode left = parseMultiplicitive(parser);
     while (parser.MatchToken(TokenType.Operation))
     {
         switch ((string)parser.CurrentToken().Value)
         {
             case "+":
                 parser.AcceptToken(TokenType.Operation);
                 left = new BinaryOpNode(BinaryOperation.Addition, left, parseMultiplicitive(parser));
                 continue;
             case "-":
                 parser.AcceptToken(TokenType.Operation);
                 left = new BinaryOpNode(BinaryOperation.Subtraction, left, parseMultiplicitive(parser));
                 continue;
             default:
                 break;
         }
         break;
     }
     return left;
 }
Example #9
0
        private static Node ParseBooleanAnd(Parser parser)
        {
            Node left = ParseEquals(parser);

            if (parser.AcceptToken(TokenType.Operator, "&&"))
            {
                return(new BinaryOperationNode(BinaryOperation.BooleanAnd, left, ParseBooleanAnd(parser)));
            }
            else
            {
                return(left);
            }
        }
Example #10
0
        private static Node ParseInstanceOf(Parser parser)
        {
            Node left = ParseBooleanOr(parser);

            if (parser.AcceptToken(TokenType.Operator, "is"))
            {
                return(new BinaryOperationNode(BinaryOperation.InstanceOf, left, ParseInstanceOf(parser)));
            }
            else
            {
                return(left);
            }
        }
 private static AstNode parseComparison(Parser parser)
 {
     AstNode left = parseFunctionCall(parser);
     while (parser.MatchToken(TokenType.Comparison))
     {
         switch ((string)parser.CurrentToken().Value)
         {
             case ">":
                 parser.AcceptToken(TokenType.Comparison);
                 left = new BinaryOpNode(BinaryOperation.GreaterThan, left, parseFunctionCall(parser));
                 continue;
             case "<":
                 parser.AcceptToken(TokenType.Comparison);
                 left = new BinaryOpNode(BinaryOperation.LessThan, left, parseFunctionCall(parser));
                 continue;
             default:
                 break;
         }
         break;
     }
     return left;
 }
Example #12
0
        public static AstNode Parse(Parser.Parser parser)
        {
            parser.ExpectToken(TokenType.Identifier, "while");
            parser.ExpectToken(TokenType.Parentheses, "(");
            AstNode predicate = ExpressionNode.Parse(parser);
            parser.ExpectToken(TokenType.Parentheses, ")");
            AstNode whileBody = StatementNode.Parse(parser);
            if (parser.AcceptToken(TokenType.Identifier, "else"))
            {
                AstNode elseBody = StatementNode.Parse(parser);
                return new WhileNode(predicate, whileBody, elseBody);
            }

            return new WhileNode(predicate, whileBody);
        }
Example #13
0
        public static AstNode Parse(Parser.Parser parser)
        {
            parser.ExpectToken(TokenType.Identifier, "try");
            AstNode tryBody = StatementNode.Parse(parser);
            parser.ExpectToken(TokenType.Identifier, "catch");
            AstNode catchBody = StatementNode.Parse(parser);

            if (parser.AcceptToken(TokenType.Identifier, "finally"))
            {
                AstNode finallyBody = StatementNode.Parse(parser);
                return new TryNode(tryBody, catchBody, finallyBody);
            }

            return new TryNode(tryBody, catchBody);
        }
Example #14
0
        public static Node Parse(Parser parser)
        {
            parser.ExpectToken(TokenType.Keyword, "enum");
            string name = parser.ExpectToken(TokenType.Identifier).Value;
            EnumDeclarationNode decl = new EnumDeclarationNode(name);

            parser.ExpectToken(TokenType.Brace, "{");
            int defaultVal = -1;

            while (!parser.MatchToken(TokenType.Brace, "}"))
            {
                string ident = parser.ExpectToken(TokenType.Identifier).Value;
                if (parser.AcceptToken(TokenType.Operator, "="))
                {
                    string val    = parser.ExpectToken(TokenType.Number).Value;
                    int    numVal = 0;
                    if (val != "")
                    {
                        numVal = int.Parse(val);
                    }
                    decl.Items[ident] = numVal;
                }
                else
                {
                    decl.Items[ident] = defaultVal--;
                }

                if (!parser.AcceptToken(TokenType.Comma))
                {
                    break;
                }
            }

            parser.ExpectToken(TokenType.Brace, "}");
            return(decl);
        }
Example #15
0
        public static ArgListNode Parse(Parser parser)
        {
            ArgListNode ret = new ArgListNode();
            parser.ExpectToken(TokenType.Parentheses, "(");

            while (!parser.MatchToken(TokenType.Parentheses, ")"))
            {
                ret.Children.Add(ExpressionNode.Parse(parser));
                if (!parser.AcceptToken(TokenType.Comma))
                    break;
            }

            parser.ExpectToken(TokenType.Parentheses, ")");

            return ret;
        }
Example #16
0
        public static Node Parse(Parser parser)
        {
            ArgumentsListNode argList = new ArgumentsListNode();

            parser.ExpectToken(TokenType.Parentheses, "(");
            while (!parser.MatchToken(TokenType.Parentheses, ")"))
            {
                argList.Children.Add(ExpressionNode.Parse(parser));
                if (!parser.AcceptToken(TokenType.Comma))
                {
                    break;
                }
            }
            parser.ExpectToken(TokenType.Parentheses, ")");
            return(argList);
        }
        public static ArrayInitializerNode Parse(Parser parser)
        {
            var ret = new ArrayInitializerNode();
            parser.ExpectToken(TokenType.Bracket, "[");

            while (!parser.MatchToken(TokenType.Bracket, "]"))
            {
                ret.Children.Add(ExpressionNode.Parse(parser));
                if (!parser.AcceptToken(TokenType.Comma))
                {
                    break;
                }
            }
            parser.ExpectToken(TokenType.Bracket, "]");

            return ret;
        }
        private static List <string> ParseFunctionParameters(Parser parser)
        {
            List <string> ret = new List <string>();

            parser.ExpectToken(TokenType.Parentheses, "(");
            while (!parser.MatchToken(TokenType.Parentheses, ")"))
            {
                Token param = parser.ExpectToken(TokenType.Identifier);
                ret.Add(param.Value);
                if (!parser.AcceptToken(TokenType.Comma))
                {
                    break;
                }
            }
            parser.ExpectToken(TokenType.Parentheses, ")");
            return(ret);
        }
Example #19
0
        public static ArrayInitializerNode Parse(Parser parser)
        {
            var ret = new ArrayInitializerNode();

            parser.ExpectToken(TokenType.Bracket, "[");

            while (!parser.MatchToken(TokenType.Bracket, "]"))
            {
                ret.Children.Add(ExpressionNode.Parse(parser));
                if (!parser.AcceptToken(TokenType.Comma))
                {
                    break;
                }
            }
            parser.ExpectToken(TokenType.Bracket, "]");

            return(ret);
        }
Example #20
0
        public static Node Parse(Parser parser)
        {
            parser.ExpectToken(TokenType.Keyword, "if");
            parser.ExpectToken(TokenType.Parentheses, "(");
            ExpressionNode predicate = new ExpressionNode(ExpressionNode.Parse(parser));

            parser.ExpectToken(TokenType.Parentheses, ")");
            Node ifBody = StatementNode.Parse(parser);

            if (parser.AcceptToken(TokenType.Keyword, "else"))
            {
                return(new IfNode(predicate, ifBody, StatementNode.Parse(parser)));
            }
            else
            {
                return(new IfNode(predicate, ifBody));
            }
        }
Example #21
0
        private static AstNode ParseAdditive(Parser.Parser parser)
        {
            AstNode left = ParseMultiplicative(parser);

            if (parser.AcceptToken(TokenType.Operation, "+"))
            {
                AstNode right = ParseAdditive(parser);
                return new BinOpNode(BinaryOperation.Addition, left, right);
            }
            else if (parser.AcceptToken(TokenType.Operation, "-"))
            {
                AstNode right = ParseAdditive(parser);
                return new BinOpNode(BinaryOperation.Subtraction, left, right);
            }
            else
            {
                return left;
            }
        }
Example #22
0
        public static AstNode Parse(Parser.Parser parser)
        {
            parser.ExpectToken(TokenType.Identifier, "func");
            string name = parser.ExpectToken(TokenType.Identifier).Value.ToString();
            parser.ExpectToken(TokenType.Parentheses, "(");

            List<string> result = new List<string>();
            while (parser.MatchToken(TokenType.Identifier))
            {
                result.Add(parser.ExpectToken(TokenType.Identifier).Value.ToString());
                if (!parser.AcceptToken(TokenType.Comma))
                    break;
            }

            parser.ExpectToken(TokenType.Parentheses, ")");
            AstNode body = StatementNode.Parse(parser);

            return new FuncNode(name, result, body);
        }
Example #23
0
        private static Node ParseTerm(Parser parser)
        {
            Token token = null;

            if (parser.AcceptToken(TokenType.Identifier, ref token))
            {
                return(new IdentifierNode(token.Value));
            }
            else if (parser.AcceptToken(TokenType.Number, ref token))
            {
                return(new NumberNode(int.Parse(token.Value)));
            }
            else if (parser.AcceptToken(TokenType.String, ref token))
            {
                return(new StringNode(token.Value));
            }
            else if (parser.AcceptToken(TokenType.Parentheses, "("))
            {
                Node expr = Parse(parser);
                parser.ExpectToken(TokenType.Parentheses, ")");
                return(expr);
            }
            else if (parser.AcceptToken(TokenType.Keyword, "true"))
            {
                return(new BooleanTrueNode());
            }
            else if (parser.AcceptToken(TokenType.Keyword, "false"))
            {
                return(new BooleanFalseNode());
            }
            else if (parser.AcceptToken(TokenType.Keyword, "this"))
            {
                return(new ThisNode());
            }
            return(null);
        }
Example #24
0
 private static AstNode ParseUnary(Parser.Parser parser)
 {
     if (parser.AcceptToken(TokenType.UnaryOperation, "!"))
     {
         return new UnaryOpNode(UnaryOperation.Not, ParseUnary(parser));
     }
     else if (parser.AcceptToken(TokenType.Operation, "-"))
     {
         return new UnaryOpNode(UnaryOperation.Negate, ParseUnary(parser));
     }
     else if (parser.AcceptToken(TokenType.UnaryOperation, "~"))
     {
         return new UnaryOpNode(UnaryOperation.Complement, ParseUnary(parser));
     }
     else
     {
         return ParseFunctionCall(parser);
     }
 }
Example #25
0
 private static AstNode ParseFunctionCall(Parser.Parser parser, AstNode left)
 {
     if (parser.AcceptToken(TokenType.Parentheses, "("))
     {
         return ParseFunctionCall(parser, new FunctionCallNode(left, ArgListNode.Parse(parser)));
     }
     else if (parser.AcceptToken(TokenType.Bracket, "["))
     {
         return ParseFunctionCall(parser, new ArrayGetNode(left, ArrayIndexerNode.Parse(parser)));
     }
     else
     {
         return left;
     }
 }
Example #26
0
        private static AstNode ParseAssignment(Parser.Parser parser)
        {
            AstNode left = ParseEquality(parser);

            if (parser.AcceptToken(TokenType.Assignment))
            {
                AstNode right = ParseAssignment(parser);
                return new BinOpNode(BinaryOperation.Assignment, left, right);
            }
            else if (parser.AcceptToken(TokenType.OpAssign))
            {
                var assigntype = GetBinaryOp(parser.PreviousToken().Value.ToString());
                var right = ParseAssignment(parser);
                return new BinOpNode(BinaryOperation.Assignment, assigntype, left, right);
            }
            else
            {
                return left;
            }
        }
        private static AstNode parseTerm(Parser parser)
        {
            if ((string)parser.CurrentToken(1).Value == ":")
            {
                LabelNode lnode;
                if (parser.MatchToken(TokenType.Identifier))
                    lnode = new LabelNode((string)parser.ExpectToken(TokenType.Identifier).Value);
                else if (parser.MatchToken(TokenType.Number))
                    lnode = new LabelNode(Convert.ToString(parser.ExpectToken(TokenType.Number).Value));
                else
                    throw new Exception("Unknown label type " + parser.CurrentToken().TokenType + " " + parser.CurrentToken().Value);

                parser.ExpectToken(TokenType.Identifier, ":");
                return lnode;
            }
            else if (parser.MatchToken(TokenType.Number))
                return new NumberNode(Convert.ToDouble(parser.ExpectToken(TokenType.Number).Value));
            else if (parser.AcceptToken(TokenType.Parentheses, "("))
            {
                AstNode statement = ExpressionNode.Parse(parser);
                parser.ExpectToken(TokenType.Parentheses, ")");
                return statement;
            }
            else if (parser.MatchToken(TokenType.Identifier, "THEN"))
            {
                CodeBlockNode block = new CodeBlockNode();
                parser.ExpectToken(TokenType.Identifier, "THEN");

                while (!parser.EndOfStream && !parser.MatchToken(TokenType.Identifier, "ENDIF") && !parser.MatchToken(TokenType.Identifier, "ELSE"))
                    block.Children.Add(StatementNode.Parse(parser));

                if (parser.MatchToken(TokenType.Identifier, "ELSE"))
                    return block;

                parser.ExpectToken(TokenType.Identifier, "ENDIF");

                return block;
            }
            else if (parser.MatchToken(TokenType.Identifier, "ELSE"))
            {
                parser.ExpectToken(TokenType.Identifier, "ELSE");
                return StatementNode.Parse(parser);
            }
            else if (parser.MatchToken(TokenType.Identifier, "DO"))
            {
                CodeBlockNode block = new CodeBlockNode();
                parser.ExpectToken(TokenType.Identifier, "DO");

                while (!parser.EndOfStream && !parser.MatchToken(TokenType.Identifier, "WEND"))
                    block.Children.Add(StatementNode.Parse(parser));

                parser.ExpectToken(TokenType.Identifier, "WEND");

                return block;
            }
            else if (parser.AcceptToken(TokenType.Identifier, "END"))
            {
                if (parser.MatchToken(TokenType.Number))
                    return new EndNode(Convert.ToInt32(parser.ExpectToken(TokenType.Number).Value));
                else
                    return new EndNode();
            }
            else if (parser.MatchToken(TokenType.String))
                return new StringNode((string)parser.ExpectToken(TokenType.String).Value);
            else if (parser.MatchToken(TokenType.Identifier))
                return new IdentifierNode((string)parser.ExpectToken(TokenType.Identifier).Value);
            else
                throw new Exception("Unexpected " + parser.CurrentToken().TokenType + " in Parser: " + parser.CurrentToken().Value + ".");
        }
Example #28
0
 private static AstNode ParseEquality(Parser.Parser parser)
 {
     AstNode left = ParseAdditive(parser);
     if (parser.AcceptToken(TokenType.Comparison, "="))
     {
         var right = ParseEquality(parser);
         return new BinOpNode(BinaryOperation.Equals, left, right);
     }
     else if (parser.AcceptToken(TokenType.Comparison, "!="))
     {
         var right = ParseEquality(parser);
         return new BinOpNode(BinaryOperation.NotEqualTo, left, right);
     }
     else if (parser.AcceptToken(TokenType.Comparison, "<"))
     {
         var right = ParseEquality(parser);
         return new BinOpNode(BinaryOperation.LessThan, left, right);
     }
     else if (parser.AcceptToken(TokenType.Comparison, ">"))
     {
         var right = ParseEquality(parser);
         return new BinOpNode(BinaryOperation.GreaterThan, left, right);
     }
     else if (parser.AcceptToken(TokenType.Comparison, "<="))
     {
         var right = ParseEquality(parser);
         return new BinOpNode(BinaryOperation.LesserOrEqual, left, right);
     }
     else if (parser.AcceptToken(TokenType.Comparison, ">="))
     {
         var right = ParseEquality(parser);
         return new BinOpNode(BinaryOperation.GreaterOrEqual, left, right);
     }
     else if (parser.AcceptToken(TokenType.Comparison, "&&"))
     {
         var right = ParseEquality(parser);
         return new BinOpNode(BinaryOperation.And, left, right);
     }
     else if (parser.AcceptToken(TokenType.Comparison, "&&"))
     {
         var right = ParseEquality(parser);
         return new BinOpNode(BinaryOperation.And, left, right);
     }
     else if (parser.AcceptToken(TokenType.Comparison, "||"))
     {
         var right = ParseEquality(parser);
         return new BinOpNode(BinaryOperation.Or, left, right);
     }
     else if (parser.AcceptToken(TokenType.Operation, "^"))
     {
         var right = ParseEquality(parser);
         return new BinOpNode(BinaryOperation.Xor, left, right);
     }
     else if (parser.AcceptToken(TokenType.Operation, "<<"))
     {
         var right = ParseEquality(parser);
         return new BinOpNode(BinaryOperation.BitshiftLeft, left, right);
     }
     else if (parser.AcceptToken(TokenType.Operation, ">>"))
     {
         var right = ParseEquality(parser);
         return new BinOpNode(BinaryOperation.BitshiftRight, left, right);
     }
     else if (parser.AcceptToken(TokenType.Operation, "&"))
     {
         var right = ParseEquality(parser);
         return new BinOpNode(BinaryOperation.BitwiseAnd, left, right);
     }
     else if (parser.AcceptToken(TokenType.Operation, "|"))
     {
         var right = ParseEquality(parser);
         return new BinOpNode(BinaryOperation.BitwiseOr, left, right);
     }
     else
     {
         return left;
     }
 }
Example #29
0
 private static AstNode ParseTerm(Parser.Parser parser)
 {
     if (parser.MatchToken(TokenType.Number))
     {
         return new NumberNode(Convert.ToDouble(parser.ExpectToken(TokenType.Number).Value));
     }
     else if (parser.AcceptToken(TokenType.Parentheses, "("))
     {
         AstNode statement = ExpressionNode.Parse(parser);
         parser.ExpectToken(TokenType.Parentheses, ")");
         return statement;
     }
     else if (parser.AcceptToken(TokenType.Bracket, "["))
     {
         AstNode statement = ArrayInitializerNode.Parse(parser);
         parser.ExpectToken(TokenType.Bracket, "]");
         return statement;
     }
     else if (parser.MatchToken(TokenType.String))
     {
         return new StringNode(parser.ExpectToken(TokenType.String).Value.ToString());
     }
     else if (parser.MatchToken(TokenType.Identifier))
     {
         return new IdentifierNode(parser.ExpectToken(TokenType.Identifier).Value.ToString());
     }
     else
     {
         throw new Exception("Unexpected in Parser: " + parser.CurrentToken().Value);
     }
 }
 private static AstNode parseMultiplicitive(Parser parser)
 {
     AstNode left = parseComparison(parser);
     while (parser.MatchToken(TokenType.Operation))
     {
         switch ((string)parser.CurrentToken().Value)
         {
             case "*":
                 parser.AcceptToken(TokenType.Operation);
                 left = new BinaryOpNode(BinaryOperation.Multiplication, left, parseComparison(parser));
                 continue;
             case "/":
                 parser.AcceptToken(TokenType.Operation);
                 left = new BinaryOpNode(BinaryOperation.Division, left, parseComparison(parser));
                 continue;
             case "%":
                 parser.AcceptToken(TokenType.Operation);
                 left = new BinaryOpNode(BinaryOperation.Modulus, left, parseComparison(parser));
                 continue;
             case "=":
                 parser.AcceptToken(TokenType.Assignment);
                 left = new BinaryOpNode(BinaryOperation.Assignment, left, parseComparison(parser));
                 continue;
             default:
                 break;
         }
         break;
     }
     return left;
 }
Example #31
0
        private static AstNode ParseMultiplicative(Parser.Parser parser)
        {
            AstNode left = ParseUnary(parser);

            if (parser.AcceptToken(TokenType.Operation, "*"))
            {
                AstNode right = ParseMultiplicative(parser);
                return new BinOpNode(BinaryOperation.Multiplication, left, right);
            }
            else if (parser.AcceptToken(TokenType.Operation, "/"))
            {
                AstNode right = ParseMultiplicative(parser);
                return new BinOpNode(BinaryOperation.Division, left, right);
            }
            else  if (parser.AcceptToken(TokenType.Operation, "%"))
            {
                AstNode right = ParseMultiplicative(parser);
                return new BinOpNode(BinaryOperation.Modulus, left, right);
            }
            else
            {
                return left;
            }
        }