Exemplo n.º 1
0
/* Parse an and-expression string in *P.
   On success, return the parsed and-expression.
   On error, set *P->ERROR to an error string (for free()) or NULL, and return
   NULL. */
static struct expr *
parse_and(struct parsing *p)
{
	struct expr *res;

	res = parse_primary(p);
	if (res == NULL)
		return NULL;
	while (p->token == EO_AND) {
		struct expr *e2, *e;

		if (lex(p) != 0)
			goto err_res;
		e2 = parse_primary(p);
		if (e2 == NULL)
			goto err_res;
		e = parser_malloc(p, sizeof(*e));
		if (e == NULL) {
			expr_free(e2);
			goto err_res;
		}
		e->op = EO_AND;
		e->v.sub[0] = res;
		e->v.sub[1] = e2;
		res = e;
	}
	return res;

err_res:
	expr_free(res);
	return NULL;
}
Exemplo n.º 2
0
static int parse_primary (pfstate_t *pf)
{
	int result;

	if (pf->token_type == TOKEN_LPAREN) {

	  next_token (pf);
	  result = parse_expr (pf);
	  	  
	  if (pf->token_type == TOKEN_RPAREN) {
	    next_token (pf);
	  }
	  else {
	    print_error (pf, "Expected \")\" here.\n");
	    result = -1;
	  }
	}
	else if (pf->token_type == TOKEN_NOT) {
	  int e;

	  next_token (pf);
	  e = parse_primary (pf);
	  if (e < 0) result = -1;
	  else result = ! e;
	}
	else if (pf->token_type == TOKEN_FILTER_SPEC) {
	  result = parse_filter_spec (pf);
	}
	else {
	  print_error (pf, "Expected filter specification, (, or ! here.");
	  result = -1;
	}

	return (result);
}
Exemplo n.º 3
0
    PExprAST
    Parser::parse_binop_rhs(int precedence_min, PExprAST lhs)
    {
        // We will try to read operators and replace the
        // current lhs by a bigger one, until there is
        // no more tokens.
        while (true)
        {
            int token_precedence = get_token_precedence();

            // If it's not a binop or it's a binop with
            // lower precedence.
            if (token_precedence < precedence_min)
                return lhs;

            //We know it's a binop, so we read [op, prim]
            Token binop = current_tok;
            get_next_token(); // eat the binop
            PExprAST rhs = parse_primary();

            // If the next token have a stronger precedence,
            // we should compute it as belonging to rhs.
            int next_precedence = get_token_precedence();
            if (next_precedence > token_precedence)
                rhs = PExprAST(parse_binop_rhs(token_precedence + 1, rhs));

            //Otherwise, we replace the lhs by 'lhs, op, prim'
            lhs = PExprAST(new BinaryExprAST(binop, lhs, rhs));
        }
    }
Exemplo n.º 4
0
static expr *parse_primary(void)
{
	switch(tok_cur){
		case tok_ident: tok_next(); return expr_ident();
		case tok_num:   tok_next(); return expr_num(tok_cur_num);
		case tok_lparen:
		{
			expr *e;
			tok_next();
			e = parse();
			if(tok_cur != tok_rparen)
				CPP_DIE("close paren expected");
			tok_next();
			return e;
		}

		case tok_not:
		case tok_bnot:
		case tok_minus:
		{
			const e_op op = tok_cur;
			tok_next();
			return expr_new_uop(op, parse_primary());
		}

		default:
			break;
	}

	{
		char s[2];
		*s = tok_cur, s[1] = '\0';
		CPP_DIE("expression expected (got %s)", tok_cur == tok_eof ? "eof" : s);
	}
}
Exemplo n.º 5
0
Expression *ParserContext::parse_expression() {
    Expression *ret = parse_primary();

    if (ret->type() == toy_assign)
        return ret;

    return parse_binary_op_expression(ret, 0);
}
Exemplo n.º 6
0
static int parse_and_expr (pfstate_t *pf)
{
	int result;

	result = parse_primary (pf);
	if (result < 0) return (-1);

	while (pf->token_type == TOKEN_AND) {
	  int e;

	  next_token (pf);
	  e = parse_primary (pf);
	  if (e < 0) return (-1);
	  result &= e;
	}

	return (result);
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
0
Arquivo: peg.c Projeto: ctelfer/catlib
static int parse_seq(struct peg_grammar_parser *pgp, struct peg_cursor *pc,
		     int *seqp)
{
	struct peg_grammar *peg = pgp->peg;
	int seq;
	int pri;
	int nn;
	struct peg_cursor npc = *pc;
	int rv;

	seq = peg_node_new(peg, PEG_SEQUENCE, pc->line);
	if ( seq < 0 ) {
		pgp->err = PEG_ERR_NOMEM;
		return -1;
	}

	rv = parse_primary(pgp, &npc, &pri);
	if ( rv < 0 )
		goto err;
	NODE(peg, seq)->ps_pri = pri;

	while ( rv != 0 ) {
		if ( (rv = parse_primary(pgp, &npc, &nn)) < 0 )
			goto err;
		if ( rv != 0 ) {
			NODE(peg, pri)->pn_next = nn;
			pri = nn;
		}
	}

	*pc = npc;
	*seqp = seq;
	return 1;

err:
	peg_node_free(peg, seq);
	return -1;
}
Exemplo n.º 9
0
static expr *parse_rhs(expr *lhs, int priority)
{
	for(;;){
    int this_pri, next_pri;
		e_op op;
		expr *rhs;

		op = tok_cur;
		if(!is_op(op))
			return lhs; /* eof, rparen and colon covered here */

		this_pri = PRECEDENCE(op);
    if(this_pri > priority)
      return lhs;

		/* eat the op */
		tok_next();

		/* special case for ternary */
		if(op == tok_question){
			expr *if_t = parse();

			if(tok_cur != tok_colon)
				CPP_DIE("colon expected for ternary-? operator");
			tok_next();

			rhs = parse();

			lhs = expr_new_top(lhs, if_t, rhs);
		}else{
			rhs = parse_primary();

			/* now on the next op, or eof (in which case, precedence returns -1 */
			next_pri = PRECEDENCE(tok_cur);
			if(next_pri < this_pri) {
				/* next is tighter, give it our rhs as its lhs */
				rhs = parse_rhs(rhs, next_pri);
			}

			lhs = expr_op(op, lhs, rhs);
		}
  }
}
Exemplo n.º 10
0
Expression *ParserContext::parse_binary_op_expression(Expression *LHS, int min_prec) {
    int op_prec = get_prec(curtok()->type());

    while (op_prec >= min_prec) {
        TokenType op = curtok()->type();
        eat_token(op);

        Expression *RHS = parse_primary();

        int next_prec = get_prec(curtok()->type());
        while (next_prec > op_prec) {
            RHS = parse_binary_op_expression(RHS, next_prec);
            next_prec = get_prec(curtok()->type());
        }

        LHS = new BinaryOpExpr(LHS, RHS, op);

        op_prec = get_prec(curtok()->type());
    }

    return LHS;
}
Exemplo n.º 11
0
static RegExp *
parse_factor(void)
{
    RegExp *e;
    char ch;
    e = parse_primary();
    while (curtok == CLOSE || curtok == CLOSESIZE) {
	switch (curtok) {
	    case CLOSE:
		ch = yylval.op;
		while (get_next_token() == CLOSE) {
		    if (ch != yylval.op)
			ch = '*';
		}
		switch (ch) {
		    case '*':
			e = mkAlt(RegExp_new_CloseOp(e), RegExp_new_NullOp());
			break;
		    case '+':
			e = RegExp_new_CloseOp(e);
			break;
		    case '?':
			e = mkAlt(e, RegExp_new_NullOp());
			break;
		}
		break;
	    case CLOSESIZE:
		e = RegExp_new_CloseVOp(e, yylval.extop.minsize,
					yylval.extop.maxsize);
		get_next_token();	/* CLOSESIZE */
		break;
	    default:
		Scanner_fatal(in, "parse error");
		break;
	}
    }
    return e;
}
Exemplo n.º 12
0
AstNode* ParsePrimary::parse_primary(pstr_t str)
{
    switch (get_symbol(str)) {
        case SYMBOL_FIRST_NUMBER:
            return tokenNumber->parse_number(str);
            break;
        case SYMBOL_PAREN_LEFT:
            return parseParen->parse(str);
            break;
        case SYMBOL_ALPHABET:
            return parse_identifier_or_invocation(str);
            break;
        default:
            pstr_t recover = syntaxErrorHandler->invalid_char(str, __FUNCTION__);
            if (recover != line->end()) {
                return parse_primary(recover);
            } else {
                AstNode *nullnode = new AstNode();
                nullnode->strhead = str;
                nullnode->strtail = recover;
                return nullnode;
            }
    }
}
Exemplo n.º 13
0
/// binoprhs: ([+*/^-] primary)*
ex parser::parse_binop_rhs(int expr_prec, ex& lhs)
{
	exvector args;
	args.push_back(lhs);
	int binop = -1, orig_binop = -1;
	bool need_sign_flip = false;
	while (1) {
		// check if this is a binop
		if (!is_binop(token)) {
			if (args.size() > 1)
				return make_binop_expr(orig_binop, args);
			else
				return lhs;
		}
		
		// Okay, we know this is a binop.
		if (args.size() == 1)
			orig_binop = token;

		binop = token;

		// If this is a binop that binds at least as tightly as
		// the current binop, consume it, otherwise we are done.
		int tok_prec = get_tok_prec(token);
		if (tok_prec < expr_prec) {
			if (args.size() > 1)
				return make_binop_expr(orig_binop, args);
			else 
				return lhs;
		}

		get_next_tok();  // eat binop

		// Parse the primary expression after the binary operator.
		ex rhs = parse_primary();

		// If binop binds less tightly with rhs than the operator after
		// rhs, let the pending operator take rhs as its lhs.
		int next_prec = get_tok_prec(token);
		if (tok_prec < next_prec)
			rhs = parse_binop_rhs(tok_prec + 1, rhs);

		// previous operator was '+', and current one is '-'
		// (or vice a versa).
		if (need_sign_flip)
			rhs = - rhs;

		args.push_back(rhs);

		// Minimize the number of eval() and ctor calls. This is
		// crucial for a reasonable performance. If the next operator
		// is compatible with the pending one (or the same) don't create
		// the expression and continue collecting operands instead.
		if (binop == token)
			continue;
		else if (binop == '+' && token == '-') {
			need_sign_flip = token != orig_binop;
			continue;
		} else if (binop == '-' && token == '+') {
			need_sign_flip = token != orig_binop;
			continue;
		} else { 
			if (args.size() <= 1)
				bug("binop has " << args.size() << " arguments, expected >= 2");
			lhs = make_binop_expr(orig_binop, args);
			args.clear();
			args.push_back(lhs);
		}
	}
}
Exemplo n.º 14
0
 PExprAST
 Parser::parse_expr()
 {
     PExprAST lhs = parse_primary();
     return parse_binop_rhs(0, lhs);
 }
Exemplo n.º 15
0
static expr *parse(void)
{
  return parse_rhs(parse_primary(), MAX_PRI);
}
Exemplo n.º 16
0
static AVEvalExpr * parse_pow(Parser *p, int *sign){
    *sign= (*p->s == '+') - (*p->s == '-');
    p->s += *sign&1;
    return parse_primary(p);
}