예제 #1
0
static bool parse_expr(ExprParseState *state)
{
  /* Temporarily set the constant expression evaluation barrier */
  int prev_last_jmp = state->last_jmp;
  int start = state->last_jmp = state->ops_count;

  CHECK_ERROR(parse_or(state));

  if (state->token == TOKEN_IF) {
    /* Ternary IF expression in python requires swapping the
     * main body with condition, so stash the body opcodes. */
    int size = state->ops_count - start;
    int bytes = size * sizeof(ExprOp);

    ExprOp *body = MEM_mallocN(bytes, "driver if body");
    memcpy(body, state->ops + start, bytes);

    state->last_jmp = state->ops_count = start;
    state->stack_ptr--;

    /* Parse condition. */
    if (!parse_next_token(state) || !parse_or(state) || state->token != TOKEN_ELSE ||
        !parse_next_token(state)) {
      MEM_freeN(body);
      return false;
    }

    int jmp_else = parse_add_jump(state, OPCODE_JMP_ELSE);

    /* Add body back. */
    memcpy(parse_alloc_ops(state, size), body, bytes);
    MEM_freeN(body);

    state->stack_ptr++;

    int jmp_end = parse_add_jump(state, OPCODE_JMP);

    /* Parse the else block. */
    parse_set_jump(state, jmp_else);

    CHECK_ERROR(parse_expr(state));

    parse_set_jump(state, jmp_end);
  }
  /* If no actual jumps happened, restore previous barrier */
  else if (state->last_jmp == start) {
    state->last_jmp = prev_last_jmp;
  }

  return true;
}
예제 #2
0
/* Parse STRING.
   On success, return the parsed expression tree.
   On error, set *ERROR to an error string (for free()) or NULL, and return
   NULL.  (*ERROR == NULL is allowed to handle out-of-memory errors) */
struct expr *
expr_parse(const char *string, char **error)
{
	struct parsing p;
	struct expr *res;

	p.error = error;
	p.token_value = NULL;
	p.src = string;
	if (lex(&p) != 0)
		goto err;
	if (p.token == T_EOF) {
		*error = strdup("Empty expression");
		goto err;
	}
	res = parse_or(&p);
	if (res != NULL && p.token != T_EOF) {
		expr_free(res);
		*error = NULL;
		asprintf(error, "Unexpected trailing token `%.*s'",
			 p.token_len, p.token_start);
		goto err;
	}
	free(p.token_value);
	return res;

err:
	free(p.token_value);
	return NULL;
}
예제 #3
0
파일: mpick.c 프로젝트: Duncaen/mblaze
static struct expr *
parse_inner()
{
	if (token("prune")) {
		struct expr *e = mkexpr(EXPR_PRUNE);
		return e;
	} else if (token("print")) {
		struct expr *e = mkexpr(EXPR_PRINT);
		return e;
	} else if (token("!")) {
		struct expr *e = parse_cmp();
		struct expr *not = mkexpr(EXPR_NOT);
		not->a.expr = e;
		return not;
	} else if (token("(")) {
		struct expr *e = parse_or();
		if (token(")"))
			return e;
		parse_error("missing ) at '%.15s'", pos);
		return 0;
	} else {
		parse_error("unknown expression at '%.15s'", pos);
		return 0;
	}
}
예제 #4
0
파일: mpick.c 프로젝트: Duncaen/mblaze
static struct expr *
parse_expr(char *s)
{
	pos = s;
	struct expr *e = parse_or();
	if (*pos)
		parse_error("trailing garbage at '%.15s'", pos);
	return e;
}
예제 #5
0
/* Parse a primary-expression string in *P.
   On success, return the parsed primary-expression.
   On error, set *P->ERROR to an error string (for free()) or NULL, and return
   NULL. */
static struct expr *
parse_primary(struct parsing *p)
{
	struct expr *e;

	switch (p->token) {
	case EO_NOT: {
		struct expr *res;

		if (lex(p) != 0)
			return NULL;
		e = parse_primary(p);
		if (e == NULL)
			return NULL;
		res = parser_malloc(p, sizeof(*res));
		if (res == NULL)
			goto err_e;
		res->op = EO_NOT;
		res->v.sub[0] = e;
		return res;
	}

	case T_LEFT_PAREN: {
		if (lex(p) != 0)
			return NULL;
		e = parse_or(p);
		if (e == NULL)
			return NULL;
		if (p->token != T_RIGHT_PAREN) {
			*p->error = NULL;
			asprintf(p->error, "Right paren expected, got `%.*s'",
				 p->token_len, p->token_start);
			goto err_e;
		}
		if (lex(p) != 0)
			goto err_e;
		return e;
	}

	case T_FIELD_ESCAPE: case T_STRING:
		return parse_comparison(p);

	default:
		*p->error = NULL;
		asprintf(p->error, "Unexpected token `%.*s'", p->token_len,
			 p->token_start);
		return NULL;
	}
	abort();		/* Should never get here */

err_e:
	expr_free(e);
	return NULL;
}
예제 #6
0
bool WhereMatcher::parse_and() {
  bool left = parse_or();
  Token t = stream_get();

  if(t.first == bool_and) {
	bool right = parse_and();
    return left && right;
  } else {
    if (t.first != value_undefined_type)
      stream_unget(t);
    return left;
  }
}
예제 #7
0
static bool parse_or(ExprParseState *state)
{
  CHECK_ERROR(parse_and(state));

  if (state->token == TOKEN_OR) {
    int jump = parse_add_jump(state, OPCODE_JMP_OR);

    CHECK_ERROR(parse_next_token(state) && parse_or(state));

    parse_set_jump(state, jump);
  }

  return true;
}