// Generated by TinyPG v1.3 available at www.codeproject.com

using System;
using System.Collections.Generic;

namespace DotPrograms
{
    #region Parser

    public partial class Parser 
    {
        private Scanner scanner;
        private ParseTree tree;
        
        public Parser(Scanner scanner)
        {
            this.scanner = scanner;
        }

        public ParseTree Parse(string input)
        {
            tree = new ParseTree();
            return Parse(input, tree);
        }

        public ParseTree Parse(string input, ParseTree tree)
        {
            scanner.Init(input);

            this.tree = tree;
            ParseStart(tree);
            tree.Skipped = scanner.Skipped;

            return tree;
        }

        private void ParseStart(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.Start), "Start");
            parent.Nodes.Add(node);


            
            tok = scanner.LookAhead(TokenType.FUNCTION, TokenType.VARIABLE, TokenType.BOOLEANLITERAL, TokenType.DECIMALINTEGERLITERAL, TokenType.HEXINTEGERLITERAL, TokenType.REALLITERAL, TokenType.STRINGLITERAL, TokenType.BRACKETOPEN, TokenType.LABEL, TokenType.PLUS, TokenType.MINUS, TokenType.NOT, TokenType.ASSIGN);
            if (tok.Type == TokenType.FUNCTION
                || tok.Type == TokenType.VARIABLE
                || tok.Type == TokenType.BOOLEANLITERAL
                || tok.Type == TokenType.DECIMALINTEGERLITERAL
                || tok.Type == TokenType.HEXINTEGERLITERAL
                || tok.Type == TokenType.REALLITERAL
                || tok.Type == TokenType.STRINGLITERAL
                || tok.Type == TokenType.BRACKETOPEN
                || tok.Type == TokenType.LABEL
                || tok.Type == TokenType.PLUS
                || tok.Type == TokenType.MINUS
                || tok.Type == TokenType.NOT
                || tok.Type == TokenType.ASSIGN)
            {
                ParseExpression(node);
            }

            
            tok = scanner.Scan(TokenType.EOF);
            n = node.CreateNode(tok, tok.ToString() );
            node.Token.UpdateRange(tok);
            node.Nodes.Add(n);
            if (tok.Type != TokenType.EOF) {
                tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EOF.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                return;
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseFunction(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.Function), "Function");
            parent.Nodes.Add(node);


            
            tok = scanner.Scan(TokenType.FUNCTION);
            n = node.CreateNode(tok, tok.ToString() );
            node.Token.UpdateRange(tok);
            node.Nodes.Add(n);
            if (tok.Type != TokenType.FUNCTION) {
                tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.FUNCTION.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                return;
            }

            
            tok = scanner.Scan(TokenType.BRACKETOPEN);
            n = node.CreateNode(tok, tok.ToString() );
            node.Token.UpdateRange(tok);
            node.Nodes.Add(n);
            if (tok.Type != TokenType.BRACKETOPEN) {
                tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.BRACKETOPEN.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                return;
            }

            
            tok = scanner.LookAhead(TokenType.FUNCTION, TokenType.VARIABLE, TokenType.BOOLEANLITERAL, TokenType.DECIMALINTEGERLITERAL, TokenType.HEXINTEGERLITERAL, TokenType.REALLITERAL, TokenType.STRINGLITERAL, TokenType.BRACKETOPEN, TokenType.LABEL, TokenType.PLUS, TokenType.MINUS, TokenType.NOT, TokenType.ASSIGN, TokenType.SEMICOLON);
            if (tok.Type == TokenType.FUNCTION
                || tok.Type == TokenType.VARIABLE
                || tok.Type == TokenType.BOOLEANLITERAL
                || tok.Type == TokenType.DECIMALINTEGERLITERAL
                || tok.Type == TokenType.HEXINTEGERLITERAL
                || tok.Type == TokenType.REALLITERAL
                || tok.Type == TokenType.STRINGLITERAL
                || tok.Type == TokenType.BRACKETOPEN
                || tok.Type == TokenType.LABEL
                || tok.Type == TokenType.PLUS
                || tok.Type == TokenType.MINUS
                || tok.Type == TokenType.NOT
                || tok.Type == TokenType.ASSIGN
                || tok.Type == TokenType.SEMICOLON)
            {
                ParseParams(node);
            }

            
            tok = scanner.Scan(TokenType.BRACKETCLOSE);
            n = node.CreateNode(tok, tok.ToString() );
            node.Token.UpdateRange(tok);
            node.Nodes.Add(n);
            if (tok.Type != TokenType.BRACKETCLOSE) {
                tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.BRACKETCLOSE.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                return;
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParsePrimaryExpression(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.PrimaryExpression), "PrimaryExpression");
            parent.Nodes.Add(node);

            tok = scanner.LookAhead(TokenType.FUNCTION, TokenType.VARIABLE, TokenType.BOOLEANLITERAL, TokenType.DECIMALINTEGERLITERAL, TokenType.HEXINTEGERLITERAL, TokenType.REALLITERAL, TokenType.STRINGLITERAL, TokenType.BRACKETOPEN, TokenType.LABEL);
            switch (tok.Type)
            {
                case TokenType.FUNCTION:
                    ParseFunction(node);
                    break;
                case TokenType.VARIABLE:
                    ParseVariable(node);
                    break;
                case TokenType.BOOLEANLITERAL:
                case TokenType.DECIMALINTEGERLITERAL:
                case TokenType.HEXINTEGERLITERAL:
                case TokenType.REALLITERAL:
                case TokenType.STRINGLITERAL:
                    ParseLiteral(node);
                    break;
                case TokenType.BRACKETOPEN:
                    ParseParenthesizedExpression(node);
                    break;
                case TokenType.LABEL:
                    ParseLabel(node);
                    break;
                default:
                    tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, 0, tok.StartPos, tok.StartPos, tok.Length));
                    break;
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseParenthesizedExpression(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.ParenthesizedExpression), "ParenthesizedExpression");
            parent.Nodes.Add(node);


            
            tok = scanner.Scan(TokenType.BRACKETOPEN);
            n = node.CreateNode(tok, tok.ToString() );
            node.Token.UpdateRange(tok);
            node.Nodes.Add(n);
            if (tok.Type != TokenType.BRACKETOPEN) {
                tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.BRACKETOPEN.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                return;
            }

            
            ParseExpression(node);

            
            tok = scanner.Scan(TokenType.BRACKETCLOSE);
            n = node.CreateNode(tok, tok.ToString() );
            node.Token.UpdateRange(tok);
            node.Nodes.Add(n);
            if (tok.Type != TokenType.BRACKETCLOSE) {
                tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.BRACKETCLOSE.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                return;
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseUnaryExpression(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.UnaryExpression), "UnaryExpression");
            parent.Nodes.Add(node);

            tok = scanner.LookAhead(TokenType.FUNCTION, TokenType.VARIABLE, TokenType.BOOLEANLITERAL, TokenType.DECIMALINTEGERLITERAL, TokenType.HEXINTEGERLITERAL, TokenType.REALLITERAL, TokenType.STRINGLITERAL, TokenType.BRACKETOPEN, TokenType.LABEL, TokenType.PLUS, TokenType.MINUS, TokenType.NOT);
            switch (tok.Type)
            {
                case TokenType.FUNCTION:
                case TokenType.VARIABLE:
                case TokenType.BOOLEANLITERAL:
                case TokenType.DECIMALINTEGERLITERAL:
                case TokenType.HEXINTEGERLITERAL:
                case TokenType.REALLITERAL:
                case TokenType.STRINGLITERAL:
                case TokenType.BRACKETOPEN:
                case TokenType.LABEL:
                    ParsePrimaryExpression(node);
                    break;
                case TokenType.PLUS:

                    
                    tok = scanner.Scan(TokenType.PLUS);
                    n = node.CreateNode(tok, tok.ToString() );
                    node.Token.UpdateRange(tok);
                    node.Nodes.Add(n);
                    if (tok.Type != TokenType.PLUS) {
                        tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.PLUS.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                        return;
                    }

                    
                    ParseUnaryExpression(node);
                    break;
                case TokenType.MINUS:

                    
                    tok = scanner.Scan(TokenType.MINUS);
                    n = node.CreateNode(tok, tok.ToString() );
                    node.Token.UpdateRange(tok);
                    node.Nodes.Add(n);
                    if (tok.Type != TokenType.MINUS) {
                        tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.MINUS.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                        return;
                    }

                    
                    ParseUnaryExpression(node);
                    break;
                case TokenType.NOT:

                    
                    tok = scanner.Scan(TokenType.NOT);
                    n = node.CreateNode(tok, tok.ToString() );
                    node.Token.UpdateRange(tok);
                    node.Nodes.Add(n);
                    if (tok.Type != TokenType.NOT) {
                        tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.NOT.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                        return;
                    }

                    
                    ParseUnaryExpression(node);
                    break;
                default:
                    tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, 0, tok.StartPos, tok.StartPos, tok.Length));
                    break;
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParsePowerExpression(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.PowerExpression), "PowerExpression");
            parent.Nodes.Add(node);


            
            ParseUnaryExpression(node);

            
            tok = scanner.LookAhead(TokenType.POWER);
            while (tok.Type == TokenType.POWER)
            {

                
                tok = scanner.Scan(TokenType.POWER);
                n = node.CreateNode(tok, tok.ToString() );
                node.Token.UpdateRange(tok);
                node.Nodes.Add(n);
                if (tok.Type != TokenType.POWER) {
                    tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.POWER.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                    return;
                }

                
                ParseUnaryExpression(node);
            tok = scanner.LookAhead(TokenType.POWER);
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseMultiplicativeExpression(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.MultiplicativeExpression), "MultiplicativeExpression");
            parent.Nodes.Add(node);


            
            ParsePowerExpression(node);

            
            tok = scanner.LookAhead(TokenType.ASTERIKS, TokenType.SLASH, TokenType.PERCENT);
            while (tok.Type == TokenType.ASTERIKS
                || tok.Type == TokenType.SLASH
                || tok.Type == TokenType.PERCENT)
            {

                
                tok = scanner.LookAhead(TokenType.ASTERIKS, TokenType.SLASH, TokenType.PERCENT);
                switch (tok.Type)
                {
                    case TokenType.ASTERIKS:
                        tok = scanner.Scan(TokenType.ASTERIKS);
                        n = node.CreateNode(tok, tok.ToString() );
                        node.Token.UpdateRange(tok);
                        node.Nodes.Add(n);
                        if (tok.Type != TokenType.ASTERIKS) {
                            tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.ASTERIKS.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                            return;
                        }
                        break;
                    case TokenType.SLASH:
                        tok = scanner.Scan(TokenType.SLASH);
                        n = node.CreateNode(tok, tok.ToString() );
                        node.Token.UpdateRange(tok);
                        node.Nodes.Add(n);
                        if (tok.Type != TokenType.SLASH) {
                            tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.SLASH.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                            return;
                        }
                        break;
                    case TokenType.PERCENT:
                        tok = scanner.Scan(TokenType.PERCENT);
                        n = node.CreateNode(tok, tok.ToString() );
                        node.Token.UpdateRange(tok);
                        node.Nodes.Add(n);
                        if (tok.Type != TokenType.PERCENT) {
                            tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.PERCENT.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                            return;
                        }
                        break;
                    default:
                        tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, 0, tok.StartPos, tok.StartPos, tok.Length));
                        break;
                }

                
                ParsePowerExpression(node);
            tok = scanner.LookAhead(TokenType.ASTERIKS, TokenType.SLASH, TokenType.PERCENT);
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseAdditiveExpression(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.AdditiveExpression), "AdditiveExpression");
            parent.Nodes.Add(node);


            
            ParseMultiplicativeExpression(node);

            
            tok = scanner.LookAhead(TokenType.PLUS, TokenType.MINUS);
            while (tok.Type == TokenType.PLUS
                || tok.Type == TokenType.MINUS)
            {

                
                tok = scanner.LookAhead(TokenType.PLUS, TokenType.MINUS);
                switch (tok.Type)
                {
                    case TokenType.PLUS:
                        tok = scanner.Scan(TokenType.PLUS);
                        n = node.CreateNode(tok, tok.ToString() );
                        node.Token.UpdateRange(tok);
                        node.Nodes.Add(n);
                        if (tok.Type != TokenType.PLUS) {
                            tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.PLUS.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                            return;
                        }
                        break;
                    case TokenType.MINUS:
                        tok = scanner.Scan(TokenType.MINUS);
                        n = node.CreateNode(tok, tok.ToString() );
                        node.Token.UpdateRange(tok);
                        node.Nodes.Add(n);
                        if (tok.Type != TokenType.MINUS) {
                            tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.MINUS.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                            return;
                        }
                        break;
                    default:
                        tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, 0, tok.StartPos, tok.StartPos, tok.Length));
                        break;
                }

                
                ParseMultiplicativeExpression(node);
            tok = scanner.LookAhead(TokenType.PLUS, TokenType.MINUS);
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseConcatEpression(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.ConcatEpression), "ConcatEpression");
            parent.Nodes.Add(node);


            
            ParseAdditiveExpression(node);

            
            tok = scanner.LookAhead(TokenType.AMP);
            while (tok.Type == TokenType.AMP)
            {

                
                tok = scanner.Scan(TokenType.AMP);
                n = node.CreateNode(tok, tok.ToString() );
                node.Token.UpdateRange(tok);
                node.Nodes.Add(n);
                if (tok.Type != TokenType.AMP) {
                    tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.AMP.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                    return;
                }

                
                ParseAdditiveExpression(node);
            tok = scanner.LookAhead(TokenType.AMP);
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseRelationalExpression(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.RelationalExpression), "RelationalExpression");
            parent.Nodes.Add(node);


            
            ParseConcatEpression(node);

            
            tok = scanner.LookAhead(TokenType.LESSTHAN, TokenType.LESSEQUAL, TokenType.GREATERTHAN, TokenType.GREATEREQUAL);
            if (tok.Type == TokenType.LESSTHAN
                || tok.Type == TokenType.LESSEQUAL
                || tok.Type == TokenType.GREATERTHAN
                || tok.Type == TokenType.GREATEREQUAL)
            {

                
                tok = scanner.LookAhead(TokenType.LESSTHAN, TokenType.LESSEQUAL, TokenType.GREATERTHAN, TokenType.GREATEREQUAL);
                switch (tok.Type)
                {
                    case TokenType.LESSTHAN:
                        tok = scanner.Scan(TokenType.LESSTHAN);
                        n = node.CreateNode(tok, tok.ToString() );
                        node.Token.UpdateRange(tok);
                        node.Nodes.Add(n);
                        if (tok.Type != TokenType.LESSTHAN) {
                            tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.LESSTHAN.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                            return;
                        }
                        break;
                    case TokenType.LESSEQUAL:
                        tok = scanner.Scan(TokenType.LESSEQUAL);
                        n = node.CreateNode(tok, tok.ToString() );
                        node.Token.UpdateRange(tok);
                        node.Nodes.Add(n);
                        if (tok.Type != TokenType.LESSEQUAL) {
                            tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.LESSEQUAL.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                            return;
                        }
                        break;
                    case TokenType.GREATERTHAN:
                        tok = scanner.Scan(TokenType.GREATERTHAN);
                        n = node.CreateNode(tok, tok.ToString() );
                        node.Token.UpdateRange(tok);
                        node.Nodes.Add(n);
                        if (tok.Type != TokenType.GREATERTHAN) {
                            tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.GREATERTHAN.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                            return;
                        }
                        break;
                    case TokenType.GREATEREQUAL:
                        tok = scanner.Scan(TokenType.GREATEREQUAL);
                        n = node.CreateNode(tok, tok.ToString() );
                        node.Token.UpdateRange(tok);
                        node.Nodes.Add(n);
                        if (tok.Type != TokenType.GREATEREQUAL) {
                            tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.GREATEREQUAL.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                            return;
                        }
                        break;
                    default:
                        tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, 0, tok.StartPos, tok.StartPos, tok.Length));
                        break;
                }

                
                ParseConcatEpression(node);
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseEqualityExpression(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.EqualityExpression), "EqualityExpression");
            parent.Nodes.Add(node);


            
            ParseRelationalExpression(node);

            
            tok = scanner.LookAhead(TokenType.EQUAL, TokenType.NOTEQUAL);
            while (tok.Type == TokenType.EQUAL
                || tok.Type == TokenType.NOTEQUAL)
            {

                
                tok = scanner.LookAhead(TokenType.EQUAL, TokenType.NOTEQUAL);
                switch (tok.Type)
                {
                    case TokenType.EQUAL:
                        tok = scanner.Scan(TokenType.EQUAL);
                        n = node.CreateNode(tok, tok.ToString() );
                        node.Token.UpdateRange(tok);
                        node.Nodes.Add(n);
                        if (tok.Type != TokenType.EQUAL) {
                            tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EQUAL.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                            return;
                        }
                        break;
                    case TokenType.NOTEQUAL:
                        tok = scanner.Scan(TokenType.NOTEQUAL);
                        n = node.CreateNode(tok, tok.ToString() );
                        node.Token.UpdateRange(tok);
                        node.Nodes.Add(n);
                        if (tok.Type != TokenType.NOTEQUAL) {
                            tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.NOTEQUAL.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                            return;
                        }
                        break;
                    default:
                        tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, 0, tok.StartPos, tok.StartPos, tok.Length));
                        break;
                }

                
                ParseRelationalExpression(node);
            tok = scanner.LookAhead(TokenType.EQUAL, TokenType.NOTEQUAL);
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseConditionalAndExpression(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.ConditionalAndExpression), "ConditionalAndExpression");
            parent.Nodes.Add(node);


            
            ParseEqualityExpression(node);

            
            tok = scanner.LookAhead(TokenType.AMPAMP);
            while (tok.Type == TokenType.AMPAMP)
            {

                
                tok = scanner.Scan(TokenType.AMPAMP);
                n = node.CreateNode(tok, tok.ToString() );
                node.Token.UpdateRange(tok);
                node.Nodes.Add(n);
                if (tok.Type != TokenType.AMPAMP) {
                    tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.AMPAMP.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                    return;
                }

                
                ParseEqualityExpression(node);
            tok = scanner.LookAhead(TokenType.AMPAMP);
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseConditionalOrExpression(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.ConditionalOrExpression), "ConditionalOrExpression");
            parent.Nodes.Add(node);


            
            ParseConditionalAndExpression(node);

            
            tok = scanner.LookAhead(TokenType.PIPEPIPE);
            while (tok.Type == TokenType.PIPEPIPE)
            {

                
                tok = scanner.Scan(TokenType.PIPEPIPE);
                n = node.CreateNode(tok, tok.ToString() );
                node.Token.UpdateRange(tok);
                node.Nodes.Add(n);
                if (tok.Type != TokenType.PIPEPIPE) {
                    tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.PIPEPIPE.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                    return;
                }

                
                ParseConditionalAndExpression(node);
            tok = scanner.LookAhead(TokenType.PIPEPIPE);
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseAssignmentExpression(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.AssignmentExpression), "AssignmentExpression");
            parent.Nodes.Add(node);


            
            ParseConditionalOrExpression(node);

            
            tok = scanner.LookAhead(TokenType.QUESTIONMARK);
            if (tok.Type == TokenType.QUESTIONMARK)
            {

                
                tok = scanner.Scan(TokenType.QUESTIONMARK);
                n = node.CreateNode(tok, tok.ToString() );
                node.Token.UpdateRange(tok);
                node.Nodes.Add(n);
                if (tok.Type != TokenType.QUESTIONMARK) {
                    tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.QUESTIONMARK.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                    return;
                }

                
                ParseAssignmentExpression(node);

                
                tok = scanner.Scan(TokenType.COLON);
                n = node.CreateNode(tok, tok.ToString() );
                node.Token.UpdateRange(tok);
                node.Nodes.Add(n);
                if (tok.Type != TokenType.COLON) {
                    tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.COLON.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                    return;
                }

                
                ParseAssignmentExpression(node);
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseExpression(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.Expression), "Expression");
            parent.Nodes.Add(node);


            
            tok = scanner.LookAhead(TokenType.FUNCTION, TokenType.VARIABLE, TokenType.BOOLEANLITERAL, TokenType.DECIMALINTEGERLITERAL, TokenType.HEXINTEGERLITERAL, TokenType.REALLITERAL, TokenType.STRINGLITERAL, TokenType.BRACKETOPEN, TokenType.LABEL, TokenType.PLUS, TokenType.MINUS, TokenType.NOT);
            if (tok.Type == TokenType.FUNCTION
                || tok.Type == TokenType.VARIABLE
                || tok.Type == TokenType.BOOLEANLITERAL
                || tok.Type == TokenType.DECIMALINTEGERLITERAL
                || tok.Type == TokenType.HEXINTEGERLITERAL
                || tok.Type == TokenType.REALLITERAL
                || tok.Type == TokenType.STRINGLITERAL
                || tok.Type == TokenType.BRACKETOPEN
                || tok.Type == TokenType.LABEL
                || tok.Type == TokenType.PLUS
                || tok.Type == TokenType.MINUS
                || tok.Type == TokenType.NOT)
            {
                ParseAssignmentExpression(node);
            }

            
            tok = scanner.LookAhead(TokenType.ASSIGN);
            if (tok.Type == TokenType.ASSIGN)
            {

                
                tok = scanner.Scan(TokenType.ASSIGN);
                n = node.CreateNode(tok, tok.ToString() );
                node.Token.UpdateRange(tok);
                node.Nodes.Add(n);
                if (tok.Type != TokenType.ASSIGN) {
                    tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.ASSIGN.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                    return;
                }

                
                ParseAssignmentExpression(node);
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseParams(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.Params), "Params");
            parent.Nodes.Add(node);


            
            ParseExpression(node);

            
            tok = scanner.LookAhead(TokenType.SEMICOLON);
            while (tok.Type == TokenType.SEMICOLON)
            {

                
                tok = scanner.Scan(TokenType.SEMICOLON);
                n = node.CreateNode(tok, tok.ToString() );
                node.Token.UpdateRange(tok);
                node.Nodes.Add(n);
                if (tok.Type != TokenType.SEMICOLON) {
                    tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.SEMICOLON.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                    return;
                }

                
                ParseExpression(node);
            tok = scanner.LookAhead(TokenType.SEMICOLON);
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseLiteral(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.Literal), "Literal");
            parent.Nodes.Add(node);

            tok = scanner.LookAhead(TokenType.BOOLEANLITERAL, TokenType.DECIMALINTEGERLITERAL, TokenType.HEXINTEGERLITERAL, TokenType.REALLITERAL, TokenType.STRINGLITERAL);
            switch (tok.Type)
            {
                case TokenType.BOOLEANLITERAL:
                    tok = scanner.Scan(TokenType.BOOLEANLITERAL);
                    n = node.CreateNode(tok, tok.ToString() );
                    node.Token.UpdateRange(tok);
                    node.Nodes.Add(n);
                    if (tok.Type != TokenType.BOOLEANLITERAL) {
                        tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.BOOLEANLITERAL.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                        return;
                    }
                    break;
                case TokenType.DECIMALINTEGERLITERAL:
                case TokenType.HEXINTEGERLITERAL:
                    ParseIntegerLiteral(node);
                    break;
                case TokenType.REALLITERAL:
                    ParseRealLiteral(node);
                    break;
                case TokenType.STRINGLITERAL:
                    ParseStringLiteral(node);
                    break;
                default:
                    tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, 0, tok.StartPos, tok.StartPos, tok.Length));
                    break;
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseIntegerLiteral(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.IntegerLiteral), "IntegerLiteral");
            parent.Nodes.Add(node);

            tok = scanner.LookAhead(TokenType.DECIMALINTEGERLITERAL, TokenType.HEXINTEGERLITERAL);
            switch (tok.Type)
            {
                case TokenType.DECIMALINTEGERLITERAL:
                    tok = scanner.Scan(TokenType.DECIMALINTEGERLITERAL);
                    n = node.CreateNode(tok, tok.ToString() );
                    node.Token.UpdateRange(tok);
                    node.Nodes.Add(n);
                    if (tok.Type != TokenType.DECIMALINTEGERLITERAL) {
                        tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.DECIMALINTEGERLITERAL.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                        return;
                    }
                    break;
                case TokenType.HEXINTEGERLITERAL:
                    tok = scanner.Scan(TokenType.HEXINTEGERLITERAL);
                    n = node.CreateNode(tok, tok.ToString() );
                    node.Token.UpdateRange(tok);
                    node.Nodes.Add(n);
                    if (tok.Type != TokenType.HEXINTEGERLITERAL) {
                        tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.HEXINTEGERLITERAL.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                        return;
                    }
                    break;
                default:
                    tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, 0, tok.StartPos, tok.StartPos, tok.Length));
                    break;
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseRealLiteral(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.RealLiteral), "RealLiteral");
            parent.Nodes.Add(node);

            tok = scanner.Scan(TokenType.REALLITERAL);
            n = node.CreateNode(tok, tok.ToString() );
            node.Token.UpdateRange(tok);
            node.Nodes.Add(n);
            if (tok.Type != TokenType.REALLITERAL) {
                tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.REALLITERAL.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                return;
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseStringLiteral(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.StringLiteral), "StringLiteral");
            parent.Nodes.Add(node);

            tok = scanner.Scan(TokenType.STRINGLITERAL);
            n = node.CreateNode(tok, tok.ToString() );
            node.Token.UpdateRange(tok);
            node.Nodes.Add(n);
            if (tok.Type != TokenType.STRINGLITERAL) {
                tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.STRINGLITERAL.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                return;
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseVariable(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.Variable), "Variable");
            parent.Nodes.Add(node);

            tok = scanner.Scan(TokenType.VARIABLE);
            n = node.CreateNode(tok, tok.ToString() );
            node.Token.UpdateRange(tok);
            node.Nodes.Add(n);
            if (tok.Type != TokenType.VARIABLE) {
                tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.VARIABLE.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                return;
            }

            parent.Token.UpdateRange(node.Token);
        }

        private void ParseLabel(ParseNode parent)
        {
            Token tok;
            ParseNode n;
            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.Label), "Label");
            parent.Nodes.Add(node);

            tok = scanner.Scan(TokenType.LABEL);
            n = node.CreateNode(tok, tok.ToString() );
            node.Token.UpdateRange(tok);
            node.Nodes.Add(n);
            if (tok.Type != TokenType.LABEL) {
                tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.LABEL.ToString(), 0x1001, 0, tok.StartPos, tok.StartPos, tok.Length));
                return;
            }

            parent.Token.UpdateRange(node.Token);
        }


    }

    #endregion Parser
}
