Example #1
0
void Parser::parseRHS(/* ASTNode* LHS, */ unsigned MinPrec) {
  unsigned NextTokPrec = getOperatorPrecedence(lex.peek());
  
  while (1) {
    // If this token has a lower precedence than we are allowed to parse (e.g.
    // because we are called recursively, or because the token is not a binop),
    // then we are done!
    if (NextTokPrec < MinPrec)
      return /* LHS */;
    
    // Consume the operator, saving the operator token for error reporting.
    Token OpToken = lex.peek();
    lex.consume();
    
    // Special case handling for the ternary operator
    /* ASTNode* TernaryMiddle = 0 */
    if (NextTokPrec == Precedence::Conditional) {
      if (lex.peek().type != Token::COLON)
        /* TernaryMiddle = */ parseExpression();
      
      // Eat the colon
      lex.consume(Token::COLON);
    }
    
    // Parse another leaf here for the RHS of the operator.
    /* ASTNode* RHS = */ parseUnaryExpr();
    
    // Remember the precedence of this operator and get the precedence of the
    // operator immediately to the right of the RHS.
    unsigned ThisPrec = NextTokPrec;
    NextTokPrec = getOperatorPrecedence(lex.peek());
    
    // Assignment and conditional expressions are right-associative.
    bool isRightAssoc = ThisPrec == Precedence::Conditional ||
                        ThisPrec == Precedence::Assignment;
    
    // Get the precedence of the operator to the right of the RHS.  If it binds
    // more tightly with RHS than we do, evaluate it completely first.
    if (ThisPrec < NextTokPrec ||
        (ThisPrec == NextTokPrec && isRightAssoc)) {
      // If this is left-associative, only parse things on the RHS that bind
      // more tightly than the current operator.  If it is left-associative, it
      // is okay, to bind exactly as tightly.  For example, compile A=B=C=D as
      // A=(B=(C=D)), where each paren is a level of recursion here.
      /* RHS =*/ parseRHS(/* RHS, */ ThisPrec + !isRightAssoc);

      NextTokPrec = getOperatorPrecedence(lex.peek());
    }
    assert(NextTokPrec <= ThisPrec && "Recursion didn't work!");
    
    /*
    if (TernaryMiddle)
      LHS = new TernaryASTNode(LHS, TernaryMiddle, RHS);
    else
      LHS = new ASTNode(OpToken, LHS, RHS);
    */
  }
}
Example #2
0
void RecreatorImpl::recreateUnaryOperator()
{
    auto operand = moveTopString();

    appendUnaryOperator();
    auto operator_precedence = getOperatorPrecedence();

    appendUnaryOperand(std::move(operand), operator_precedence);

    setTopPrecedence(operator_precedence);
    setTopUnaryOperatorPrecedence(operator_precedence);
}
Example #3
0
void RecreatorImpl::recreateBinaryOperator()
{
    auto rhs = stack.top();
    pop();

    auto operator_precedence = getOperatorPrecedence();

    appendLeftOperand(operator_precedence);
    appendBinaryOperator();
    appendRightOperand(rhs, operator_precedence);

    setTopPrecedence(operator_precedence);
    setTopUnaryOperatorPrecedence(rhs.unary_operator_precedence);
}
Example #4
0
std::queue<std::string> Parser::createPostFix(const std::string &input, bool& failed)
{
    std::queue<std::string> output;
    std::stack<std::string> operators;
    std::vector<std::string> tokens = parseStringToToken(input, failed);
    if(!failed) {
        for(unsigned int i = 0; i < tokens.size(); i++)
         {
             if(isdigit(tokens[i][0]) || tokens[i][0] == '#')
             {
                 output.push(tokens[i]);
             }
             //TO DO
             //If functions (sin,cos,log...)
             else if(tokens[i] != "(" && tokens[i] != ")") //assume token is an operator (Functions not implemented)
             {
                 if(!operators.empty())
                 {
                     int tokensPrecedence = getOperatorPrecedence(tokens[i]);
                     int topTokenPrecedence = getOperatorPrecedence(operators.top());
                     bool isLeftAssociative = testLeftAssociativity(tokens[i]);
                     bool isOperator = (operators.top() != "(" && operators.top() != ")");
                     bool isEmpty = false;
                     while(isOperator && !isEmpty && ((isLeftAssociative  && tokensPrecedence >= topTokenPrecedence) ||
                             (!isLeftAssociative && tokensPrecedence > topTokenPrecedence)))
                     {
                         output.push(operators.top());
                         operators.pop();
                         isEmpty = operators.empty();
                         if(!isEmpty)
                         {
                             isOperator = (operators.top() != "(" && operators.top() != ")");
                             topTokenPrecedence = getOperatorPrecedence(operators.top());
                         }
                     }
                 }
                 operators.push(tokens[i]);
             }
             else if(tokens[i] == "(")
             {
                 operators.push(tokens[i]);
             }
             else if(tokens[i] == ")")
             {
                 if(!operators.empty()) {
                     while(operators.top() != "(")
                     {
                         output.push(operators.top());
                         operators.pop();
                     }
                     operators.pop();
                 }
                 else {
                     failed = true;
                     errorCode_ = ERR_SYNTAX;
                 }
             }
             else
             {
                 failed = true;
                 errorCode_ = ERR_SYNTAX;
             }
         }
         while(!operators.empty())
         {
             output.push(operators.top());
             operators.pop();
         }
    }
    if(!operators.empty()) {
        failed = true;
        errorCode_ = ERR_SYNTAX;
    }
    return output;
}
double in_eval(char *exp) {
    int exp_length = strlen(exp), numOfVars = 0;
	struct operator_stack *os = create_operator_stack(exp_length / 2);
    char *token, *copy, *vars[10] = {NULL}, rpn_exp[1024] = "";
    double value = 0;
    
    copy = (char *) malloc(sizeof(char) * exp_length);
    strcpy(copy, exp);

    token = strtok(copy, " ");

	bool previousIsOperator = false,
		 previousIsLeftParenthese = false,
		 varsSet = false;

    while (token != NULL) {
        errorOccurs = true;
		varsSet = false;

        if (isNumeric(token) && sscanf(token, "%lf", &value) > 0) {
			if (!(strlen(rpn_exp) == 0 || previousIsOperator || previousIsLeftParenthese)) return value;

			for (int i = 0; i < numOfVars; i++) {
				setVariable(vars[i], value);
				vars[i] = NULL;
				varsSet = true;
			}

			numOfVars = 0;

            errorOccurs = false;
			previousIsOperator = false;
			previousIsLeftParenthese = false;

			concat_double(rpn_exp, value);
        } else if (variableValid(token)) {
			if (!(strlen(rpn_exp) == 0 || previousIsOperator
						|| previousIsLeftParenthese)) return value;

			char operator = *(token + strlen(token) + 1);

			if (operator == '=') {
				vars[numOfVars++] = token;

				errorOccurs = false;
			} else {
				value = getVariable(token);

				errorOccurs = !variableExists(token);

				concat_double(rpn_exp, value);
			}

			previousIsOperator = false;
			previousIsLeftParenthese = false;
        } else if (isOperator(token) || isParenthese(token)) {
			if ((isOperator(token) && previousIsOperator)
					|| (strcmp(token, ")") == 0 && strlen(rpn_exp) == 0)) return value;
           
			if (numOfVars > 0) return value;

			char *op = NULL;

			if (strcmp(token, "(") == 0) {
				push_operator(os, token);

				previousIsLeftParenthese = true;
			} else if (strcmp(token, ")") == 0) {
				op = peek_operator(os);

				if (strcmp(op, "(") == 0) return value;

				op = pop_operator(os);

				while (strcmp(op, "(") != 0) {
					if (strcmp(op, ")") == 0) return value;

					concat_operator(rpn_exp, op);

					op = pop_operator(os);
				}
				
				previousIsLeftParenthese = false;
			} else {
				int pre1 = -1, pre2 = getOperatorPrecedence(token);
				if (os->top > -1) pre1 = getOperatorPrecedence(peek_operator(os));

				while (pre2 > pre1 && pre1 > 0 && os->top > -1) {
					concat_operator(rpn_exp, pop_operator(os));

					if (os->top > -1) pre1 = getOperatorPrecedence(peek_operator(os));
				}

				push_operator(os, token);

				previousIsOperator = true;
				previousIsLeftParenthese = false;
			}

			errorOccurs = false;
		 } else if (strcmp(token, "=") == 0) {
			 errorOccurs = false;
		 } else {
			 return value;
		 }

		if (errorOccurs) return value;

        token = strtok(NULL, " ");
    }

	while (os->top > -1) concat_operator(rpn_exp, pop_operator(os));

    free(copy);
	free_operator_stack(os);

	if (!(varsSet || errorOccurs)) value = rpn_eval(rpn_exp);

	return value;
}