コード例 #1
0
SymbolListPtr CodeBlock::convert_postfix(SymbolListPtr p) {
	// data structs
	unique_ptr<stack<SymbolPtr>> op_stack = unique_ptr<stack<SymbolPtr>>(new stack<SymbolPtr>);
	SymbolListPtr unpostfix_symbols = SymbolListPtr(new SymbolList());
	
	// shunting yard (modified for unary operators!)
	for (auto i = p->begin(); i !=
		 p->end(); i++) {
		if (is_operand(*i)) {
			unpostfix_symbols->push_back(*i);
			if (!op_stack->empty()) {
				if (is_unary(op_stack->top())) {
					unpostfix_symbols->push_back(op_stack->top());
					op_stack->pop();
				}
			}
		} else if (is_operator(*i)) {
			if (is_unary((*i))) {
				op_stack->push(*i);
			} else {
				while (!op_stack->empty()
					   && !is_lparen(op_stack->top())
					   && compare_ops(*i, op_stack->top()) <= 0) {
					unpostfix_symbols->push_back(op_stack->top());
					op_stack->pop();
				}
				op_stack->push(*i);
			}
		} else if (is_lparen(*i)) {
			op_stack->push(*i);
		} else if (is_rparen(*i)) {
			while (!op_stack->empty()) {
				if (is_lparen(op_stack->top())) {
					op_stack->pop();
					if (!op_stack->empty()) {
						if (is_unary(op_stack->top())) {
							unpostfix_symbols->push_back(op_stack->top());
							op_stack->pop();
						}
					}
					break;
				}
				unpostfix_symbols->push_back(op_stack->top());
				op_stack->pop();
			}
		}
	}
	while(!op_stack->empty()) {
		unpostfix_symbols->push_back(op_stack->top());
		op_stack->pop();
	}
	
	// set the temp symbols as the postfix stuff
	return unpostfix_symbols;
}
コード例 #2
0
ファイル: eval.c プロジェクト: cgrobbelaar/svofski
void infix2rpn(char *expr, RPNEntry ***rpne, int *nrpne) {
    Array *rpn = array_new(32, 16);
    Stack *stack_ops = stack_new(16);
    //static char token[64];
    char *token;
    int tokenlen;
    int i;

    int uminus = 1;
    int inoperand = 0;
    //printf("%s:-> ", expr);

    char lookahead;

    for(token = gettoken(expr, &tokenlen, &lookahead);token != NULL; token = gettoken(NULL, &tokenlen, &lookahead)) {
        if (uminus) {
            if (*token == T_MINUS) {
                *token = T_UMINUS;
            }
            uminus = 0;
        }

        if (is_function(token, tokenlen)) {
            stack_push(stack_ops, token);
        } else if (is_operand(token)) {
            array_add(rpn, token);
        } else if (is_arg_separator(token)) {
            while(!stack_empty(stack_ops) && !is_lparen(stack_peek(stack_ops))) {
                array_add(rpn, stack_pop(stack_ops));
            }
        } else if (is_operator(token)) {
            uminus = 1;
            if (stack_empty(stack_ops)) {
                stack_push(stack_ops, token);
            } else {
                if (compare_ops(token, stack_peek(stack_ops))) {
                    array_add(rpn, stack_pop(stack_ops));
                }
                stack_push(stack_ops, token);
            }
        } else if (is_lparen(token)) {
            uminus = 1;
            stack_push(stack_ops, token);
        } else if (is_rparen(token)) {
            while(!stack_empty(stack_ops) && !is_lparen(stack_peek(stack_ops))) {
                array_add(rpn, stack_pop(stack_ops));
            }
            stack_pop(stack_ops);
        } else {
            // errorski
        }
    }
    while (!stack_empty(stack_ops)) {
        array_add(rpn, stack_pop(stack_ops));
    }

    stack_free(&stack_ops);
    *rpne = (RPNEntry **)malloc(rpn->count * sizeof(RPNEntry*));
    for (i = 0; i < rpn->count; i++) {
        token = array_get(rpn, i);
        (*rpne)[i] = new_rpnentry(token, strlen(token));
    }
    *nrpne = rpn->count;
    array_free(&rpn);
}
コード例 #3
0
TokenSeq *glsl_expand(TokenSeq *ts, bool recursive)
{
   TokenSeq *res = NULL;

   STACK_CHECK();

   while (ts || !res) {
      if (!recursive && ts == NULL)
         ts = next_tokenseq();

      if (ts == NULL)
         break;

      if (!glsl_tokenlist_contains(ts->hide, ts->token)) {
         Macro *m = glsl_macrolist_find(directive_macros, ts->token);

         if (m != NULL) {
            switch (m->type) {
            case MACRO_OBJECT:
               ts = glsl_tokenseq_destructive_reverse(subst(m->body, NULL, NULL, glsl_tokenlist_construct(ts->token, ts->hide), NULL), ts->next);
               continue;   // effective tail call
            case MACRO_FUNCTION:
               if (!recursive && ts->next == NULL)
                  ts->next = next_tokenseq();

               if (ts->next && is_lparen(ts->next->token)) {
                  int formal_count = glsl_tokenlist_length(m->args);

                  int depth = 0;
                  int count = 0;

                  /*
                     gather up actual parameters
                  */

                  TokenSeq *tail = ts->next->next;
                  TokenSeq *curr = NULL;

                  TokenSeqList *actuals = NULL;

                  while (true) {
                     if (!recursive && tail == NULL)
                        tail = next_tokenseq();

                     if (tail == NULL)
                        glsl_compile_error(ERROR_PREPROCESSOR, 1, g_LineNumber, "mismatched parenthesis in macro invocation");

                     if (is_lparen(tail->token))
                        depth++;
                     if (is_rparen(tail->token))
                     {
                        if (depth == 0)
                           break;
                        else
                           depth--;
                     }
                     if (is_comma(tail->token))
                        if (depth == 0) {
                           actuals = glsl_tokenseqlist_construct(glsl_tokenseq_destructive_reverse(curr, NULL), actuals);
                           count++;

                           tail = tail->next;
                           curr = NULL;

                           continue;
                        }

                     curr = glsl_tokenseq_construct(tail->token, tail->hide, curr);      

                     tail = tail->next;
                  }

                  if (count > 0 || formal_count == 1 || curr != NULL) {
                     actuals = glsl_tokenseqlist_construct(glsl_tokenseq_destructive_reverse(curr, NULL), actuals);
                     count++;
                  }  

                  /*
                     check against arity of macro
                  */

                  if (count == formal_count) {
                     ts = glsl_tokenseq_destructive_reverse(subst(m->body, m->args, actuals, glsl_tokenlist_construct(ts->token, glsl_tokenlist_intersect(ts->hide, tail->hide)), NULL), tail->next);
                     continue;   // effective tail call
                  } else 
                     glsl_compile_error(ERROR_PREPROCESSOR, 1, g_LineNumber, "arity mismatch in macro invocation");
               }
               break;
            case MACRO_LINE:
               ts = glsl_tokenseq_construct(glsl_token_construct_ppnumberi(g_LineNumber), NULL, ts->next);
               break;
            case MACRO_FILE:
               ts = glsl_tokenseq_construct(glsl_token_construct_ppnumberi(g_FileNumber), NULL, ts->next);
               break;
            default:
               UNREACHABLE();
               break;
            }
         }
      }

      res = glsl_tokenseq_construct(ts->token, ts->hide, res);
      ts = ts->next;
   }

   return glsl_tokenseq_destructive_reverse(res, NULL);
}