ExpressionNode Conditional()
        {
            ExpressionNode c = LazyOr();
            ExpressionNode root = c;
            if (Try("?"))
            {
                root = new ExpressionNode(new Token(TokenType.Conditional, "?"));
                ExpressionNode t = Conditional();
                Expect(":");
                ExpressionNode e = Conditional();
                root.AddChild(c);
                root.AddChild(t);
                root.AddChild(e);
            }

            return root;
        }
 /// <summary>
 /// The Sizeof operation
 /// </summary>
 /// <returns>An expression node created based on the operation</returns>
 protected ExpressionNode Sizeof()
 {
     Token sizeofToken = new Token(TokenType.SizeOf, "sizeof");
     if (Try("sizeof"))
     {
         isInSizeOf = true;
         ExpressionNode root = new ExpressionNode(sizeofToken);
         ExpressionNode child = Primary();
         root.AddChild(child);
         isInSizeOf = false;
         return root;
     }
     else
         return Literal();
 }
 /// <summary>
 /// The Unary operation
 /// </summary>
 /// <returns>An expression node created based on the operation</returns>
 protected ExpressionNode Unary()
 {
     ExpressionNode root;
     ExpressionNode x;
     if (Try("!"))
     {
         root = new ExpressionNode(new Token(TokenType.Not, "!"));
         x = Unary();
         root.AddChild(x);
     }
     else if (Try("~"))
     {
         root = new ExpressionNode(new Token(TokenType.BitNot, "~"));
         x = Unary();
         root.AddChild(x);
     }
     else if (Try("-"))
     {
         root = new ExpressionNode(new Token(TokenType.Negative, "-"));
         x = Unary();
         root.AddChild(x);
     }
     else if (Try("+"))
     {
         root = new ExpressionNode(new Token(TokenType.Positive, "+"));
         x = Unary();
         root.AddChild(x);
     }
     else if (Try("*"))
     {
         root = new ExpressionNode(new Token(TokenType.Dereference, "*"));
         x = Unary();
         root.AddChild(x);
     }
     else
         root = Primary();
     return root;
 }
 /// <summary>
 /// The compare operation
 /// (equals to, equals not, 
 /// less than, less than or equals to, 
 /// greater than, greater than or equals to)
 /// </summary>
 /// <returns>An expression node created based on the operation</returns>
 protected ExpressionNode Relation()
 {
     ExpressionNode x = Shift();
     ExpressionNode root = x;
     while (true)
     {
         if (Try("=="))
         {
             ExpressionNode y = Shift();
             x = root;
             root = new ExpressionNode(new Token(TokenType.Equal, "=="));
             root.AddChild(x);
             root.AddChild(y);
         }
         else if (Try("!="))
         {
             ExpressionNode y = Shift();
             x = root;
             root = new ExpressionNode(new Token(TokenType.NotEqual, "!="));
             root.AddChild(x);
             root.AddChild(y);
         }
         else if (Try(">="))
         {
             ExpressionNode y = Shift();
             x = root;
             root = new ExpressionNode(new Token(TokenType.GreaterOrEqual, ">="));
             root.AddChild(x);
             root.AddChild(y);
         }
         else if (Try("<="))
         {
             ExpressionNode y = Shift();
             x = root;
             root = new ExpressionNode(new Token(TokenType.LesserOrEqual, "<="));
             root.AddChild(x);
             root.AddChild(y);
         }
         else if (Try(">"))
         {
             ExpressionNode y = Shift();
             x = root;
             root = new ExpressionNode(new Token(TokenType.Greater, ">"));
             root.AddChild(x);
             root.AddChild(y);
         }
         else if (Try("<"))
         {
             ExpressionNode y = Shift();
             x = root;
             root = new ExpressionNode(new Token(TokenType.Lesser, "<"));
             root.AddChild(x);
             root.AddChild(y);
         }
         else
             break;
     }
     return root;
 }
 /// <summary>
 /// The bit shift operation
 /// </summary>
 /// <returns>An expression node created based on the operation</returns>
 protected ExpressionNode Shift()
 {
     ExpressionNode x = Add();
     ExpressionNode root = x;
     while (true)
     {
         if (Try("<<"))
         {
             ExpressionNode y = Add();
             x = root;
             root = new ExpressionNode(new Token(TokenType.ShiftLeft, "<<"));
             root.AddChild(x);
             root.AddChild(y);
         }
         else if (Try(">>"))
         {
             ExpressionNode y = Add();
             x = root;
             root = new ExpressionNode(new Token(TokenType.ShiftRight, ">>"));
             root.AddChild(x);
             root.AddChild(y);
         }
         else
             break;
     }
     return root;
 }
        /// <summary>
        /// The Literal operation
        /// </summary>
        /// <returns>An expression node created based on the operation</returns>
        protected ExpressionNode Literal()
        {
            if (currentToken.Text.Length > 0)
                if (currentToken.Type == TokenType.Integer)
                {
                    int res;
                    if (TryConvertNumber(currentToken.Text, out res))
                    {
                        ExpressionNode integer = new ExpressionNode(
                            new Token(TokenType.Integer, res.ToString(CultureInfo.InvariantCulture)));
                        GetNextToken();
                        return integer;
                    }
                    else
                    {
                        throw new ExpressionEvaluatorException(
                            string.Format(CultureInfo.InvariantCulture, "invalid number '{0}'", currentToken.Text));
                    }
                }
                else if (currentToken.Type == TokenType.String)
                {
                    int x;

                    if (!context.TryResolveSymbol(currentToken.Text, out x))
                    {
                        string tokenText = currentToken.Text;
                        while (true)
                        {
                            if (context.Variables != null
                                && !context.Variables.ContainsKey(currentToken.Text)
                                && !DatatypeInfoProvider.IsPredefinedDatatype(currentToken.Text)
                                && !DatatypeInfoProvider.isPredefinedModifier(currentToken.Text))
                            {
                                string typeInfo;
                                if (context.TryResolveCustomType(currentToken.Text, out typeInfo))
                                {
                                    tokenText = typeInfo;
                                    break;
                                }
                                else
                                {
                                    context.ReportError(
                                        string.Format(CultureInfo.InvariantCulture, "cannot resolve symbol '{0}'", currentToken.Text));
                                    break;
                                }
                            }
                            if (context.Variables != null
                                && context.Variables.ContainsKey(currentToken.Text))
                            {
                                tokenText = currentToken.Text;
                                break;
                            }

                            // treat predefinedModifier as empty node
                            if (DatatypeInfoProvider.isPredefinedModifier(currentToken.Text))
                            {
                                GetNextToken();
                            }
                            else if (DatatypeInfoProvider.IsPredefinedDatatype(currentToken.Text))
                            {
                                tokenText = currentToken.Text;
                                break;
                            }
                        }

                        // in order to get pointer type size and avoid related issue
                        bool isPointerType = false;
                        GetNextToken();
                        if (isInSizeOf)
                        {
                            while (currentToken.Text == "*")
                            {
                                GetNextToken();
                                isPointerType = true;
                            }
                        }

                        if (isPointerType)
                        {
                            ExpressionNode integer = new ExpressionNode(
                                new Token(TokenType.Integer, "4"));
                            return integer;
                        }
                        ExpressionNode variable = new ExpressionNode(
                            new Token(TokenType.Variable, tokenText));

                        return variable;
                    }
                    else if (isInSizeOf)
                    {
                        string tokenText = currentToken.Text;

                        GetNextToken();

                        //ignoring other expression
                        while (currentToken.Text != ")")
                        {
                            GetNextToken();
                        }

                        return new ExpressionNode(
                            new Token(TokenType.Variable, tokenText));
                    }
                    else
                    {
                        GetNextToken();
                        return new ExpressionNode(
                            new Token(TokenType.Integer, x.ToString(CultureInfo.InvariantCulture)));
                    }
                }
                else
                    throw new ExpressionEvaluatorException(
                        string.Format(CultureInfo.InvariantCulture, "unexpected token '{0}'", currentToken));
            else
                throw new ExpressionEvaluatorException("unexpected end of input");
        }
 /// <summary>
 /// The Multiply operation
 /// </summary>
 /// <returns>An expression node created based on the operation</returns>
 protected ExpressionNode Multiply()
 {
     ExpressionNode x = Unary();
     ExpressionNode root = x;
     while (true)
     {
         ExpressionNode oldRoot = root;
         if (Try("*"))
         {
             ExpressionNode y = Unary();
             root = new ExpressionNode(new Token(TokenType.Multiply, "*"));
             root.AddChild(oldRoot);
             root.AddChild(y);
         }
         else if (Try("/"))
         {
             ExpressionNode y = Unary();
             root = new ExpressionNode(new Token(TokenType.Divide, "/"));
             root.AddChild(oldRoot);
             root.AddChild(y);
         }
         else if (Try("%"))
         {
             ExpressionNode y = Unary();
             root = new ExpressionNode(new Token(TokenType.Mod, "%"));
             root.AddChild(oldRoot);
             root.AddChild(y);
         }
         else
             break;
     }
     return root;
 }
 /// <summary>
 /// The Lazy OR operation
 /// </summary>
 /// <returns>An expression node created based on the operation</returns>
 protected ExpressionNode LazyOr()
 {
     ExpressionNode x = LazyAnd();
     ExpressionNode root = x;
     while (Try("||"))
     {
         ExpressionNode y = LazyAnd();
         root = new ExpressionNode(new Token(TokenType.Or, "||"));
         root.AddChild(x);
         root.AddChild(y);
     }
     return root;
 }
 /// <summary>
 /// The Lazy AND operation
 /// </summary>
 /// <returns>An expression node created based on the operation</returns>
 protected ExpressionNode LazyAnd()
 {
     ExpressionNode x = BitOr();
     ExpressionNode root = x;
     while (Try("&&"))
     {
         ExpressionNode y = BitOr();
         root = new ExpressionNode(new Token(TokenType.And, "&&"));
         root.AddChild(x);
         root.AddChild(y);
     }
     return root;
 }
 /// <summary>
 /// The Bit XOR operation
 /// </summary>
 /// <returns>An expression node created based on the operation</returns>
 protected ExpressionNode BitXor()
 {
     ExpressionNode x = BitAnd();
     ExpressionNode root = x;
     while (Try("^"))
     {
         ExpressionNode y = BitAnd();
         root = new ExpressionNode(new Token(TokenType.BitXor, "^"));
         root.AddChild(x);
         root.AddChild(y);
     }
     return root;
 }
 /// <summary>
 /// The Bit AND operation
 /// </summary>
 /// <returns>An expression node created based on the operation</returns>
 protected ExpressionNode BitAnd()
 {
     ExpressionNode x = Relation();
     ExpressionNode root = x;
     while (Try("&"))
     {
         ExpressionNode y = Relation();
         root = new ExpressionNode(new Token(TokenType.BitAnd, "&"));
         root.AddChild(x);
         root.AddChild(y);
     }
     return root;
 }
 /// <summary>
 /// The Add operation
 /// </summary>
 /// <returns>An expression node created based on the operation</returns>
 protected ExpressionNode Add()
 {
     ExpressionNode x = Multiply();
     ExpressionNode root = x;
     while (true)
     {
         ExpressionNode oldRoot = root;
         if (Try("+"))
         {
             ExpressionNode y = Multiply();
             root = new ExpressionNode(new Token(TokenType.Plus, "+"));
             root.AddChild(oldRoot);
             root.AddChild(y);
         }
         else if (Try("-"))
         {
             ExpressionNode y = Multiply();
             root = new ExpressionNode(new Token(TokenType.Minus, "-"));
             root.AddChild(oldRoot);
             root.AddChild(y);
         }
         else
             break;
     }
     return root;
 }