Esempio n. 1
0
bool Expression::infix2postfix() {
    Stack<Term> *operators = new Stack<Term>;
    Term t1, t2;
    // Verify all terms on queue
    while (!m_terms->isEmpty()) {
        m_terms->dequeue(t1);
        operators->top(t2);
        // If is a number, send to postfix queue
        if (is_number(t1)) {
            m_terms_postfix->enqueue(t1);
        // If isn't a number and the queue is empty or is
        // an opening parenthesis, send to operators stack
        } else if (operators->isEmpty() || is_opening_parenthesis(t1)) {
            // If the tokenize is right, this never should happen
            if (is_closing_parenthesis(t1)) {
                set_error(4, t1.col);
                delete operators;
                return false;
            }
            operators->push(t1);
        // If is a closing parenthesis, send all the operators
        // until the opening parenthesis to postfix queue
        } else if (is_closing_parenthesis(t1)) {
            while (!is_opening_parenthesis(t2)) {
                operators->pop(t2);
                m_terms_postfix->enqueue(t2);
                operators->top(t2);
            }
            assert(is_opening_parenthesis(t2));
            operators->pop(t2);
        // Else, remove all operators who have a minor
        // precedence and push him to operators stack
        } else {
            while (get_precedence(t1) >= get_precedence(t2) &&
                   !operators->isEmpty() && !is_opening_parenthesis(t2)) {
                operators->pop(t2);
                m_terms_postfix->enqueue(t2);
                operators->top(t2);
            }
            operators->push(t1);
        }
    }
    // Remove remaining terms on Stack
    while (!operators->isEmpty()) {
        operators->pop(t2);
        // If the tokenize is right, this never should happen
        if (is_opening_parenthesis(t2)) {
            set_error(6, t2.col);
            delete operators;
            return false;
        }
        m_terms_postfix->enqueue(t2);
    }

    // Delete operators Stack to avoid memory leak
    delete operators;

    return true;
}
Esempio n. 2
0
void i2p(char infix[])
{

	int i=0,p=0,len,type,prec;
	char next,stack[20],postfix[20];
	int get_type(char);
	int get_precedence(char);
	len=strlen(infix);

	while(i<len)
	{
		type=get_type(infix[i]);
		switch(type)
		{
			case 1:
				push(stack,infix[i]);
				break;
			case 2:
				while((next=pop(stack))!='(')
					postfix[p++]=next;
				break;
			case 3:
				postfix[p++]=infix[i];
				break;
			case 4:
				prec=get_precedence(infix[i]); 
				while(stack_empty()==False)
				{
					if(prec<=get_precedence(stack[top-1]))
						postfix[p++]=pop(stack);
					else
						break;
				}
				push(stack,infix[i]);
				break;
		}
		i++;
	}
	while(stack_empty()==False)
		postfix[p++]=pop(stack);
	postfix[p]='\0';
	printf("%s\n",postfix);
}
Esempio n. 3
0
/*
 * Parse an infix expression from a token stream
 * Returns a parse tree
 * See https://en.wikipedia.org/wiki/Shunting-yard_algorithm
 */
Token parse_infix_expression(Token tokens){
    Token operators = NULL;
    unsigned operatorsLen = 0;
    
    Token output = NULL;
    unsigned outputLen = 0;
    
    Token nextToken;
    while(tokens != NULL){
        nextToken = tokens->next;
        tokens->next = NULL;
        // if it's not a builtin, stick it in output
        if(tokens->type != BUILTIN){
            push_token_stack(tokens, &output, &outputLen);
        } else { // if it's a builtin, do magic
            // check if it's allowed to be here
            ERROR_UNLESS(!can_start_line(tokens->builtin), "statement operators not allowed in expressions")
            if(operatorsLen == 0){
                push_token_stack(tokens, &operators, &operatorsLen);
            } else if(tokens->builtin == L_PAREN){
                push_token_stack(tokens, &operators, &operatorsLen);
            } else if(tokens->builtin == R_PAREN){
                // pop operators until L_PAREN
                free_token(&tokens); // we don't need the R_PAREN
                while(operatorsLen > 0 && operators->builtin != L_PAREN)
                    pop_operator(&operators, &operatorsLen, &output, &outputLen);
                if(operatorsLen == 0){ // there was no L_PAREN, so error
                    ERROR("mismatched parentheses")
                } else {
                    // discard the L_PAREN
                    Token discard = pop_token_stack(&operators, &operatorsLen);
                    free_token(&discard);
                }
            } else if(get_precedence(tokens->builtin) > get_precedence(operators->builtin)){
                push_token_stack(tokens, &operators, &operatorsLen);
            } else {
                // we are not a parenthesis and we're lower precedence than
                // the operator on the stack, so pop it and put us there
                pop_operator(&operators, &operatorsLen, &output, &outputLen);
                push_token_stack(tokens, &operators, &operatorsLen);
            }
        }
Esempio n. 4
0
string ExpressionManager::infixToPostfix(string infixExpression){
    stack<char> symbols;
    string out_str = "";
    //do tests for the validity of the infix expression
    if(!isBalanced(infixExpression)){
        return invalid;
    }
    if(!op_num_ratio_check(infixExpression)){
        return invalid;
    }

    char exp_str[STR_BUFF_SIZE];
    exp_str[0] = '\0';
    //create a C string from the expression string
    //for use in strtok
    strcat(exp_str, infixExpression.c_str());

    char * token;

    //use strtok to tokenize the string
    //separating by spaces

    token = strtok(exp_str, " ");
    while( 1 ){
        if(token == NULL){
            while(!symbols.empty()){
                out_str += symbols.top();
                out_str += " ";
                symbols.pop();
            }
            break;
        }
        //cout << "token: " << token << "\n";
        if(is_int_num(string(token))){
                out_str += string(token);
                out_str += " ";
        } else if(is_paren( *token ) == OPEN_PAREN){
            symbols.push( *token );
        } else if(is_paren( *token ) == CLOSE_PAREN){
            char top_char = symbols.top();
            symbols.pop(); 
            while(get_precedence(top_char) > OPEN_PAREN){
                //symbols.pop();
                out_str += top_char;
                out_str += " ";
                top_char = symbols.top();
                symbols.pop();
            }
        }  else if(is_op( *token )){
            if(symbols.empty()){
                symbols.push( *token );
            } else {
                char top_char = symbols.top();
                int top_prec = get_precedence(top_char);
                int token_prec = get_precedence( *token );
                while( top_prec >= token_prec ){
                    //go through any tokens with greater than or equal precedence
                    symbols.pop();
                    out_str += top_char;
                    out_str += " ";
                    if(symbols.empty()){
                        break;
                    }
                    top_char = symbols.top();
                    top_prec = get_precedence(top_char);
                }
                symbols.push( *token );
            }
        }
        //increment to the next token
        token = strtok(NULL, " ");
    }
    
    //to remove the last part of the string (the trailing space)
    //if using C++11 you can do out_str.pop_back();
    out_str.erase(out_str.end() - 1);

    return out_str;
}
Esempio n. 5
0
uint32_t opp_parse(token_node * lookback_ptr, 
		      token_node * lookahead_ptr, 
		      token_node * list_begin, 
		      token_node * chunk_end, 
		      parsing_ctx * ctx)
{
    uint32_t parse_result = 0;
    reduction_list *main_reduction_list, *temp_reduction_list;	/* reduction_list represents where we are inside the reduction tree. */
    uint32_t end_chunk_parse = __MORE_INPUT;
    uint32_t reduction_error = 0;
    uint32_t node = 0;
    token_node * current_list_pos = list_begin;
    token_node * prev_symbol_ptr    = lookback_ptr;
    token_node * list_itr         = NULL;
    vect_stack yields_prec_stack,parsing_stack;
    token_node * last_terminal = NULL;
    uint32_t prec=0;
    vect_stack stack;
    
    init_vect_stack(&stack, ctx->NODE_ALLOC_SIZE);
    init_vect_stack(&yields_prec_stack, ctx->PREC_ALLOC_SIZE);
    init_vect_stack(&parsing_stack,     ctx->PREC_ALLOC_SIZE);

    main_reduction_list = (reduction_list *) malloc(sizeof(reduction_list));
    init_reduction_list(main_reduction_list);

    temp_reduction_list = (reduction_list *) malloc(sizeof(reduction_list));
    init_reduction_list(temp_reduction_list);

    /* set correctly last_terminal and current_pos */
    while ( !( is_terminal(current_list_pos->token) || end_chunk_parse ) ) {
	    end_chunk_parse = get_next_token(&current_list_pos, &prev_symbol_ptr, chunk_end, lookahead_ptr); 
	}
    last_terminal= is_terminal(lookback_ptr->token) ? lookback_ptr : current_list_pos;
    /* Start the parsing process. */
    while (current_list_pos != NULL) {
	/* lookup precedence between last stack terminal token and new token. */
        prec = get_precedence(current_list_pos,last_terminal);
        /*this was inserted by the guys: add the string terminator to the precedence table to remove this cruft */
        if (lookback_ptr->token == __TERM && prec == __EQ && yields_prec_stack.top_of_stack == 0) {
	     prec = __GT;
        }
	/* Invalid precedence value fetched from precedence table, abort parsing */
	if (prec == __NOP) {
	    parse_result = __PARSE_ERROR;
	    break;
	}
	/* if precedence is __EQ or __LT, we should shift */
	if (prec != __GT || yields_prec_stack.top_of_stack == 0) {
	    if (end_chunk_parse == __END_OF_INPUT) {
		parse_result = __PARSE_IN_PROGRESS;
		break;
	    }
	    /* Push token_node on top of yields_prec_stack. */
	    if (prec == __LT) {
               vect_stack_push(&yields_prec_stack, last_terminal, ctx->PREC_REALLOC_SIZE);
	    }
	    /* Get next token. */
	    assert(is_terminal(current_list_pos->token));
	    vect_stack_push(&parsing_stack, last_terminal, ctx->NODE_REALLOC_SIZE);
	    last_terminal=current_list_pos;
	    end_chunk_parse = get_next_token(&current_list_pos, &prev_symbol_ptr, chunk_end, lookahead_ptr);
	} else {
		/*clear reduction list */
	        main_reduction_list->idx_last = 0;
		/* node is the offset of the root of the vectorized reduction trie. */
		node = vect_reduction_tree[0];
		/* obtain the position of the previous yields precedence */
		prev_symbol_ptr = vect_stack_pop(&yields_prec_stack);
	        /* add pop to parsing stack to remove all the terminals up to the one 
		 which should be reduced */
		while (last_terminal!= prev_symbol_ptr && last_terminal!=NULL){
		  last_terminal=vect_stack_pop(&parsing_stack);
		}
		/* the stack pop should always be successful, as TOS !=0 
		 * it should_never get here*/
		assert(prev_symbol_ptr !=NULL);
		list_itr = prev_symbol_ptr->next;
		/* Set the first element of the reduction list to the root. */
		append_position_on_reduction_list(main_reduction_list, node);
		reduction_error = 0;

		/* starting from the previous yields precedence scan the candidate rhs and 
		 *match it against the reduction trie */
		while (list_itr != NULL && list_itr != current_list_pos && list_itr != chunk_end) {
		    /* For each available position in the reduction tree. */
		    uint32_t i;
		    for (i = 0; i < main_reduction_list->idx_last; i++) {
			reduction_step(temp_reduction_list, 
				       get_reduction_position_at_index(main_reduction_list, i), 
				       list_itr, 
		                       ctx);
		    }
		    swap_reduction_lists(&temp_reduction_list, &main_reduction_list);
		    /* erase temp_reduction_list */
		    temp_reduction_list->idx_last = 0;
		    list_itr = list_itr->next;
		    /* If there is at least one available position in the reduction tree after having considered current token, go on. */
		    if (main_reduction_list->idx_last <= 0) {
			reduction_error = 1;
			break;
		    }
		}
		
		/* Finished handle identification. */
		if (!reduction_error && vect_reduction_tree[get_reduction_position_at_index(main_reduction_list, 0)] == __GRAMMAR_SIZE) {
		    DEBUG_PRINT("Not in reducible position.\n")
			reduction_error = 1;
		}
		if (!reduction_error) {
		    call_semantics(main_reduction_list, prev_symbol_ptr, &stack, ctx);
		} else {
		    parse_result = __PARSE_NOT_RECOGNIZED;
		    break;
		}
		/* if the axiom is reached and only two terminators are left reduce and exit */
		if (lookback_ptr->token == __TERM && ctx->token_list->next == NULL && current_list_pos->token == __TERM &&
		    !is_terminal(ctx->token_list->token) && rewrite_to_axiom(ctx->token_list->token)) {
		    perform_rewrite(lookback_ptr, ctx->token_list->token, __S, &stack, ctx);
		    parse_result = __PARSE_SUCCESS;
		    break;
		}
	    }
	/* If next token is a nonterminal just move on. Eventually you might hit the terminator */
	while ( !( is_terminal(current_list_pos->token) || end_chunk_parse ) ) {
	    end_chunk_parse = get_next_token(&current_list_pos, &prev_symbol_ptr, chunk_end, lookahead_ptr);
	}
    }/*end of the parsing loop */
    cleanup_stack_and_lists(&yields_prec_stack, main_reduction_list, temp_reduction_list);
    return parse_result;
}
Esempio n. 6
0
static int compile(scriptlet *s, const char *src)
{
	compiletime c = (compiletime)calloc(1, sizeof(struct compiletime_));
	c->s = s;
	s->it_codes = 0;
	token tok;

	while ((src = get_token(src, tok)) != 0)
	{
		int precedence = get_precedence(tok);

		if (precedence)
		{
			DEBUG printf("operator '%s' precedence=%d\n", tok, precedence);
		}
		else
		{
			DEBUG printf("operand '%s'\n", tok);
		}

		if (!precedence)
		{
			push_operand(c, tok);
			continue;
		}

		if (!strcmp(tok, "("))
		{
			push_operator(c, tok, precedence);
			continue;
		}

		int top_precedence, discard = 0, empty_list;
		const char *top_op;

		while ((top_op = head_operator(c, &top_precedence, &empty_list)), !empty_list)
		{
			if (!strcmp(top_op, "(") && !strcmp(tok, ")"))
			{
				int operand_count;
				pop_operator(c, &operand_count);
				discard = 1;
				continue;
			}

			DEBUG printf("top_op = '%s' with precedence = %d\n", top_op, top_precedence);

			if (precedence > top_precedence)
				break;

			if (!compile_operator(c))
			{
				free(c);
				return 0;
			}

			if (discard)
				break;
		}

		if (!discard)
			push_operator(c, tok, precedence);
	}

	int top_precedence, empty_list;
	const char *top_op;

	while ((top_op = head_operator(c, &top_precedence, &empty_list)), !empty_list )
	{
		DEBUG printf("top_op = '%s'\n", top_op);

		if (!compile_operator(c))
		{
			free(c);
			return 0;
		}
	}

	free(c);
	return 1;
}