Exemplo n.º 1
0
// multi-rest ::=  '*' primary expr (multi-rest)
//                 '/' primary expr (multi-rest)
//                 '%' primary expr (multi-rest)
//
// assuming the first primary expr and operator has already been parsed
// this parses the 'rest' of the expression
Expr*
parse_mult_rest(Parser& p, Token_stream& ts, Token const* tok, Expr* e1)
{
  // look for the next operand
  if (Expr* e2 = parse_unary_expr(p, ts)) {
    // if there is another operator after the primary expr
    // and it is a multiplicative operator
    // then consume it.
    // the expr so far becomes the lhs operand
    // and we recurse until there are no more multiplicative operators.
    if (Token const* t = ts.next()) {
      if (is_mult_op(t->kind()))
        return parse_mult_rest(p, ts, ts.advance(), p.on_binary(tok, e1, e2));
      // return once we're done eating up multiplicative operators
      else
        return p.on_binary(tok, e1, e2);
    }
    else
      return p.on_binary(tok, e1, e2);
  }

  error("Expected expression after multiplicative expr: ");
  print(e1);
  print(tok);
  print("\n");
  return nullptr;
}
Exemplo n.º 2
0
static node_t *get_factortail(token_stack_t *stack, node_t *left_expr, GError **err)
{
    const token_t *token;
    node_t *op, *expr;
    GError *tmp_err = NULL;

    token = token_peak(stack);

    /* First check if we really have a factortail here. If not, return the
     * factor. */
    if (token == NULL) {
        g_free(token_pop(stack));
        return left_expr;
    } else if (!(token->type == TOK_OPERATOR && is_mult_op(token->val.op)))
        return left_expr;

    op = g_malloc(sizeof(node_t));
    op->left = left_expr;
    op->type = NODE_OPERATOR;
    switch (token->val.op) {
    case '*':
        op->val.op = OP_TIMES;
        break;
    case '/':
        op->val.op = OP_DIV;
        break;
    default:
        set_error(err, "Expected '*' or '/'", token);
        g_free(op);
        return left_expr;
    }
    g_free(token_pop(stack));

    /* Then there should be a factor. */
    op->right = get_factor(stack, &tmp_err);
    if (tmp_err) {
        g_propagate_error(err, tmp_err);
        return op;
    }

    /* and finally another factortail */
    expr = get_factortail(stack, op, &tmp_err);
    if (tmp_err)
        g_propagate_error(err, tmp_err);

    return expr;
}