예제 #1
0
        private Expression ParseEntityWithoutSuffixChain(TokenStream tokens, TopLevelConstruct owner)
        {
            string next = tokens.PeekValue();

            if (next == null)
            {
                tokens.ThrowEofException();
            }
            if (next == this.parser.Keywords.NULL)
            {
                return(new NullConstant(tokens.Pop(), owner));
            }
            if (next == this.parser.Keywords.TRUE)
            {
                return(new BooleanConstant(tokens.Pop(), true, owner));
            }
            if (next == this.parser.Keywords.FALSE)
            {
                return(new BooleanConstant(tokens.Pop(), false, owner));
            }

            Token peekToken = tokens.Peek();

            if (next.StartsWith("'"))
            {
                return(new StringConstant(tokens.Pop(), StringConstant.ParseOutRawValue(peekToken), owner));
            }
            if (next.StartsWith("\""))
            {
                return(new StringConstant(tokens.Pop(), StringConstant.ParseOutRawValue(peekToken), owner));
            }
            if (next == this.parser.Keywords.NEW)
            {
                return(this.ParseInstantiate(tokens, owner));
            }

            char firstChar = next[0];

            if (VARIABLE_STARTER.Contains(firstChar))
            {
                Token varToken = tokens.Pop();
                return(new Variable(varToken, varToken.Value, owner));
            }

            if (firstChar == '[')
            {
                Token             bracketToken = tokens.PopExpected("[");
                List <Expression> elements     = new List <Expression>();
                bool previousHasCommaOrFirst   = true;
                while (!tokens.PopIfPresent("]"))
                {
                    if (!previousHasCommaOrFirst)
                    {
                        tokens.PopExpected("]");                           // throws appropriate error
                    }
                    elements.Add(Parse(tokens, owner));
                    previousHasCommaOrFirst = tokens.PopIfPresent(",");
                }
                return(new ListDefinition(bracketToken, elements, owner));
            }

            if (firstChar == '{')
            {
                Token             braceToken = tokens.PopExpected("{");
                List <Expression> keys       = new List <Expression>();
                List <Expression> values     = new List <Expression>();
                bool previousHasCommaOrFirst = true;
                while (!tokens.PopIfPresent("}"))
                {
                    if (!previousHasCommaOrFirst)
                    {
                        tokens.PopExpected("}");                           // throws appropriate error
                    }
                    keys.Add(Parse(tokens, owner));
                    tokens.PopExpected(":");
                    values.Add(Parse(tokens, owner));
                    previousHasCommaOrFirst = tokens.PopIfPresent(",");
                }
                return(new DictionaryDefinition(braceToken, keys, values, owner));
            }

            if (next.Length > 2 && next.Substring(0, 2) == "0x")
            {
                Token intToken = tokens.Pop();
                int   intValue = IntegerConstant.ParseIntConstant(intToken, intToken.Value);
                return(new IntegerConstant(intToken, intValue, owner));
            }

            if (ParserContext.IsInteger(next))
            {
                Token  numberToken = tokens.Pop();
                string numberValue = numberToken.Value;

                if (tokens.IsNext("."))
                {
                    Token decimalToken = tokens.Pop();
                    if (decimalToken.HasWhitespacePrefix)
                    {
                        throw new ParserException(decimalToken, "Decimals cannot have whitespace before them.");
                    }

                    Token afterDecimal = tokens.Pop();
                    if (afterDecimal.HasWhitespacePrefix)
                    {
                        throw new ParserException(afterDecimal, "Cannot have whitespace after the decimal.");
                    }
                    if (!ParserContext.IsInteger(afterDecimal.Value))
                    {
                        throw new ParserException(afterDecimal, "Decimal must be followed by an integer.");
                    }

                    numberValue += "." + afterDecimal.Value;

                    double floatValue = FloatConstant.ParseValue(numberToken, numberValue);
                    return(new FloatConstant(numberToken, floatValue, owner));
                }

                int intValue = IntegerConstant.ParseIntConstant(numberToken, numberToken.Value);
                return(new IntegerConstant(numberToken, intValue, owner));
            }

            if (tokens.IsNext("."))
            {
                Token  dotToken    = tokens.PopExpected(".");
                string numberValue = "0.";
                Token  postDecimal = tokens.Pop();
                if (postDecimal.HasWhitespacePrefix || !ParserContext.IsInteger(postDecimal.Value))
                {
                    throw new ParserException(dotToken, "Unexpected dot.");
                }

                numberValue += postDecimal.Value;

                double floatValue;
                if (Util.ParseDouble(numberValue, out floatValue))
                {
                    return(new FloatConstant(dotToken, floatValue, owner));
                }

                throw new ParserException(dotToken, "Invalid float literal.");
            }

            throw new ParserException(tokens.Peek(), "Encountered unexpected token: '" + tokens.PeekValue() + "'");
        }
예제 #2
0
 public Expression Parse(TokenStream tokens, TopLevelConstruct owner)
 {
     return(ParseTernary(tokens, owner));
 }
예제 #3
0
        private Expression ParseEntity(TokenStream tokens, TopLevelConstruct owner)
        {
            Expression root;

            if (tokens.PopIfPresent("("))
            {
                root = this.Parse(tokens, owner);
                tokens.PopExpected(")");
            }
            else
            {
                root = ParseEntityWithoutSuffixChain(tokens, owner);
            }
            bool anySuffixes = true;

            while (anySuffixes)
            {
                if (tokens.IsNext("."))
                {
                    Token dotToken  = tokens.Pop();
                    Token stepToken = tokens.Pop();
                    // HACK alert: "class" is a valid field on a class.
                    // ParserVerifyIdentifier is invoked downstream for non-resolved fields.
                    if (stepToken.Value != this.parser.Keywords.CLASS)
                    {
                        this.parser.VerifyIdentifier(stepToken);
                    }
                    root = new DotStep(root, dotToken, stepToken, owner);
                }
                else if (tokens.IsNext("["))
                {
                    Token             openBracket     = tokens.Pop();
                    List <Expression> sliceComponents = new List <Expression>();
                    if (tokens.IsNext(":"))
                    {
                        sliceComponents.Add(null);
                    }
                    else
                    {
                        sliceComponents.Add(Parse(tokens, owner));
                    }

                    for (int i = 0; i < 2; ++i)
                    {
                        if (tokens.PopIfPresent(":"))
                        {
                            if (tokens.IsNext(":") || tokens.IsNext("]"))
                            {
                                sliceComponents.Add(null);
                            }
                            else
                            {
                                sliceComponents.Add(Parse(tokens, owner));
                            }
                        }
                    }

                    tokens.PopExpected("]");

                    if (sliceComponents.Count == 1)
                    {
                        Expression index = sliceComponents[0];
                        root = new BracketIndex(root, openBracket, index, owner);
                    }
                    else
                    {
                        root = new ListSlice(root, sliceComponents, openBracket, owner);
                    }
                }
                else if (tokens.IsNext("("))
                {
                    Token             openParen = tokens.Pop();
                    List <Expression> args      = new List <Expression>();
                    while (!tokens.PopIfPresent(")"))
                    {
                        if (args.Count > 0)
                        {
                            tokens.PopExpected(",");
                        }

                        args.Add(Parse(tokens, owner));
                    }
                    root = new FunctionCall(root, openParen, args, owner);
                }
                else if (tokens.IsNext(this.parser.Keywords.IS))
                {
                    Token  isToken    = tokens.Pop();
                    Token  classToken = tokens.Pop();
                    string className  = this.parser.PopClassNameWithFirstTokenAlreadyPopped(tokens, classToken);
                    root = new IsComparison(root, isToken, classToken, className, owner);
                }
                else
                {
                    anySuffixes = false;
                }
            }
            return(root);
        }
예제 #4
0
        /// <summary>
        /// Parser for Predicate
        /// </summary>
        /// <returns>Parsed Predicate</returns>
        public Predicate ParsePredicate()
        {
            Predicate predicate = null; //Empty predicate

            if (TokenStream.HasNext() && TokenStream.Peek(1).GetValue().ToString() == "!")
            {   //Not Predicate
                NotPredicate notPredicate = new NotPredicate();

                //Skip ! token
                NextToken("!", "! predicate", '!');

                //Parse predicate after !
                notPredicate.SetPredicate(ParsePredicate());

                predicate = notPredicate;
            }
            else
            {   //Other predicates exists out of an expression
                Expression expression = expressionParser.ParseExpression();

                if (TokenStream.HasNext() && TokenStream.Peek(1).GetValue().ToString() == ".")
                {   //IsPredicate
                    predicate = ParseIsPredicate(expression);
                }
                else
                {   //ExpressionPredicate
                    predicate = ParseExpressionPredicate(expression);
                }
            }

            //Check for && or || predicates
            if (TokenStream.HasNext() && TokenStream.Peek(1).GetValue().ToString() == "&" && TokenStream.Peek(2).GetValue().ToString() == "&")
            {   //AndPredicate
                return(ParseAndPredicate(predicate));
            }
            else if (TokenStream.HasNext() && TokenStream.Peek(1).GetValue().ToString() == "|" && TokenStream.Peek(2).GetValue().ToString() == "|")
            {   //OrPredicate
                return(ParseOrPredicate(predicate));
            }
            return(predicate);
        }