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() + "'"); }
public Expression Parse(TokenStream tokens, TopLevelConstruct owner) { return(ParseTernary(tokens, owner)); }
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); }
/// <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); }