TPParseTreeNode CFormulaParser::ParseExpression() { int token_ID = _tokenizer.LookAhead(); TPParseTreeNode expression; // Handle brackets before unary, because brackets are also "unary" if (TokenIsBracketOpen(token_ID)) { expression = ParseBracketExpression(); } else if (TokenIsUnary(token_ID)) { expression = ParseUnaryExpression(); } else if ((token_ID == kTokenIdentifier) || (token_ID == kTokenNumber)) { expression = ParseSimpleExpression(); } else { CParseErrors::Error("Unexpected token inside expression.\n" "Expecting: opening bracket, unary operator, identifier or number.\n"); return NULL; } token_ID = _tokenizer.LookAhead(); if (TokenIsBinary(token_ID)) { _tokenizer.GetToken(); // Special handling of percentaged potsized bets, // that look like modulo or percentage operators, // but lack a 2nd operand and have "Force" instead. // When ... RaiseBy 60% Force if (token_ID == kTokenOperatorPercentage) { int next_token_ID = _tokenizer.LookAhead(); if (next_token_ID == kTokenKeywordForce) { // Now we should pushback the *2nd last* token (percentage) _tokenizer.PushBackAdditionalPercentageOperator(); // and return the expression we got so far return expression; } } TPParseTreeNode second_expression = ParseExpression(); TPParseTreeNode binary_node = new CParseTreeNode(_tokenizer.LineRelative()); binary_node->MakeBinaryOperator(token_ID, expression, second_expression); write_log(preferences.debug_parser(), "[FormulaParser] Binary node %i\n", binary_node); return binary_node; } else if (token_ID == kTokenOperatorConditionalIf) { // Ternary condition TPParseTreeNode then_expression; TPParseTreeNode else_expression; ParseConditionalPartialThenElseExpressions( &then_expression, &else_expression); TPParseTreeNode ternary_node = new CParseTreeNode(_tokenizer.LineRelative()); ternary_node->MakeTernaryOperator(token_ID, expression, then_expression, else_expression); write_log(preferences.debug_parser(), "[FormulaParser] Ternary node %i\n", ternary_node); return ternary_node; } else { // We got the complete expression // No complex binary or ternary condition write_log(preferences.debug_parser(), "[FormulaParser] Expression %i\n", expression); return expression; } }
Expresion* Sintactico::ParseFactor() { if ( proximo_token.GetTipo() == punt_parentizq ) { proximo_token = analizador_lexico->ObtenerSiguienteToken(); Expresion* expr = ParseExpression(); if ( proximo_token.GetTipo() == punt_parentder ) { proximo_token = analizador_lexico->ObtenerSiguienteToken(); } else throw SyntaxException("Falta un parentesis derecho: produccion Factor",analizador_lexico->GetLineaActual()); return expr; } else if ( proximo_token.GetTipo() == lit_int || proximo_token.GetTipo() == lit_float || proximo_token.GetTipo() == lit_string || proximo_token.GetTipo() == lit_boolean || proximo_token.GetTipo() == lit_caracter ) { return ParseLiteralConstant(); } else if ( proximo_token.GetTipo() == op_suma || proximo_token.GetTipo() == op_resta || proximo_token.GetTipo() == kw_not ) { //Utilizamos Primeros ( unary-expression ) return ParseUnaryExpression(); } else if ( proximo_token.GetTipo() == id ) { string identificador = proximo_token.GetLexema(); proximo_token = analizador_lexico->ObtenerSiguienteToken(); if ( proximo_token.GetTipo() == punt_parentizq ) { list<Expresion*>args = ParseFunctionCall(); FunctionCall* func = new FunctionCall(identificador,args); return func; } else { list<Qualifier*> qualifier_list = ParseQualifiers(); Identificador* id = new Identificador(identificador,qualifier_list); return id; } } else throw SyntaxException("No se encontro un token correcto...factor",analizador_lexico->GetLineaActual() ); }
/** * Parse a binary expression, from logical-OR-expresssion to multiplicative-expression */ static AstExpression ParseBinaryExpression(int prec) { AstExpression binExpr; AstExpression expr; int newPrec; expr = ParseUnaryExpression(); /// while the following binary operater's precedence is higher than current /// binary operator's precedence, parses a higer precedence expression while (IsBinaryOP(CurrentToken) && (newPrec = Prec[BINARY_OP]) >= prec) { CREATE_AST_NODE(binExpr, Expression); binExpr->op = BINARY_OP; binExpr->kids[0] = expr; NEXT_TOKEN; binExpr->kids[1] = ParseBinaryExpression(newPrec + 1); expr = binExpr; } return expr; }
/** * unary-expression: * postfix-expression * unary-operator unary-expression * ( type-name ) unary-expression * sizeof unary-expression * sizeof ( type-name ) * * unary-operator: * ++ -- & * + - ! ~ */ static AstExpression ParseUnaryExpression() { AstExpression expr; int t; switch (CurrentToken) { case TK_INC: case TK_DEC: case TK_BITAND: case TK_MUL: case TK_ADD: case TK_SUB: case TK_NOT: case TK_COMP: CREATE_AST_NODE(expr, Expression); expr->op = UNARY_OP; NEXT_TOKEN; expr->kids[0] = ParseUnaryExpression(); return expr; case TK_LPAREN: /// When current token is (, it may be a type cast expression /// or a primary expression, we need to look ahead one token, /// if next token is type name, the expression is treated as /// a type cast expression; otherwise a primary expresion BeginPeekToken(); t = GetNextToken(); if (IsTypeName(t)) { EndPeekToken(); CREATE_AST_NODE(expr, Expression); expr->op = OP_CAST; NEXT_TOKEN; expr->kids[0] = (AstExpression)ParseTypeName(); Expect(TK_RPAREN); expr->kids[1] = ParseUnaryExpression(); return expr; } else { EndPeekToken(); return ParsePostfixExpression(); } break; case TK_SIZEOF: /// this case hase the same issue with TK_LPAREN case CREATE_AST_NODE(expr, Expression); expr->op = OP_SIZEOF; NEXT_TOKEN; if (CurrentToken == TK_LPAREN) { BeginPeekToken(); t = GetNextToken(); if (IsTypeName(t)) { EndPeekToken(); NEXT_TOKEN; /// In this case, the first kid is not an expression, /// but thanks to both type name and expression have a /// kind member to discriminate them. expr->kids[0] = (AstExpression)ParseTypeName(); Expect(TK_RPAREN); } else { EndPeekToken(); expr->kids[0] = ParseUnaryExpression(); } } else { expr->kids[0] = ParseUnaryExpression(); } return expr; default: return ParsePostfixExpression(); } }