Exemplo n.º 1
0
Arquivo: parse.c Projeto: jkdewar/rook
/*----------------------------------------------------------------------*/
static ast_expression_t *parse_term_op(parse_state_t *p, ast_expression_t *left) {
    token_t* token;

    token = peek_token(p);
    if (token == NULL) {
        return NULL;
    } else if (token->type == TK_STAR || token->type == TK_SLASH) {
        ast_expression_t *right;
        ast_expression_t *bin_op;
        ast_expression_t *term_op;

        next_token(p);
        right = parse_signed_factor(p);

        bin_op = ALLOC(sizeof(ast_expression_t));
        bin_op->tag = AST_EXPRESSION_BIN_OP;
        bin_op->u.bin_op.left = left;
        bin_op->u.bin_op.right = right;
        bin_op->u.bin_op.operation = token->type;

        term_op = parse_term_op(p, bin_op);
        return term_op != NULL ? term_op : bin_op;
    } else {
        return NULL;
    }
}
Exemplo n.º 2
0
Arquivo: parse.c Projeto: GJDuck/SMCHR
/*
 * Parse a term.
 */
static bool parse_term_op(context_t cxt, term_t *val, unsigned priority)
{
    term_t lval;
    if (!parse_term_head(cxt, &lval))
        return false;

    do
    {
        char *op_name = (char *)gc_malloc(TOKEN_MAXLEN+1);
        token_t tok = token_peek(cxt, NULL, op_name);
        
        unsigned op_priority;
        assoc_t op_assoc;

        if (!parse_maybe_op(tok) ||
            !binop_lookup(cxt->opinfo, op_name, &op_assoc, &op_priority, NULL,
                NULL) ||
            op_priority > priority)
        {
            *val = lval;
            gc_free(op_name);
            return true;
        }

        if (op_priority == priority)
        {
            switch (op_assoc)
            {
                case YFX:
                    *val = lval;
                    return true;
                case XFY:
                    break;
                case XFX:
                    parse_error(cxt, "operator `!y%s!d' associativity error",
                        op_name);
                    gc_free(op_name);
                    return false;
            }
        }

        if (!token_expect(cxt, tok))
        {
            gc_free(op_name);
            return false;
        }
        term_t rval;
        if (!parse_term_op(cxt, &rval, op_priority))
        {
            gc_free(op_name);
            return false;
        }

        atom_t atom = make_atom(gc_strdup(op_name), 2);
        gc_free(op_name);
        func_t f = make_func(atom, lval, rval);
        lval = term_func(f);
    }
    while (true);
}
Exemplo n.º 3
0
Arquivo: parse.c Projeto: GJDuck/SMCHR
/*
 * Parse a term.
 */
extern term_t parse_term(const char *filename, size_t *line, opinfo_t opinfo,
    const char *str, const char **end, varset_t *vars)
{
    struct context_s cxt_0;
    context_t cxt = &cxt_0;
    cxt->file = filename;
    cxt->line = *line;
    if (vars == NULL)
        cxt->vars = varset_init();
    else
        cxt->vars = *vars;
    cxt->opinfo = opinfo;
    cxt->str = (char *)str;
    cxt->peeked_token = TOKEN_NONE;
    cxt->peeked_val = TERM_NIL;

    term_t val;
    const char *end0;
    if (end == NULL)
        end = &end0;
    if (token_peek(cxt, NULL, NULL) == TOKEN_END)
        val = (term_t)NULL;
    else if (!parse_term_op(cxt, &val, UINT32_MAX))
        val = (term_t)NULL;
    else if (!token_expect(cxt, TOKEN_END))
        val = (term_t)NULL;
    else
    {
        if (vars != NULL)
            *vars = cxt->vars;
    }
    *end = cxt->str;
    *line = cxt->line;
    return val;
}
Exemplo n.º 4
0
Arquivo: parse.c Projeto: jkdewar/rook
/*----------------------------------------------------------------------*/
static ast_expression_t *parse_term(parse_state_t *p) {
    ast_expression_t *left;
    ast_expression_t *term_op;

    left = parse_argument(p);
    term_op = parse_term_op(p, left);
    return term_op != NULL ? term_op : left;
}
Exemplo n.º 5
0
Arquivo: parse.c Projeto: GJDuck/SMCHR
/*
 * Parse a term (no operators).
 */
static bool parse_term_head(context_t cxt, term_t *val)
{
    char *tokstr = (char *)gc_malloc(TOKEN_MAXLEN+1);
    term_t tokval;
    token_t tok = token_get(cxt, &tokval, tokstr);

    unsigned priority;
    if (parse_maybe_op(tok) &&
        unop_lookup(cxt->opinfo, tokstr, &priority, NULL))
    {
        term_t lval;
        if (!parse_term_op(cxt, &lval, priority))
        {
            gc_free(tokstr);
            return false;
        }
        atom_t atom = make_atom(gc_strdup(tokstr), 1);
        func_t f = make_func(atom, lval);
        tokval = term_func(f);
        *val = tokval;
        gc_free(tokstr);
        return true;
    }

    bool ok = true;
    term_t *args = NULL;
    switch ((int)tok)
    {
        case '(':
            if (!parse_term_op(cxt, val, UINT32_MAX) || !token_expect(cxt, ')'))
                ok = false;
            break;
        case TOKEN_NIL: case TOKEN_BOOLEAN: case TOKEN_ATOM: case TOKEN_STRING:
        case TOKEN_NUMBER:
            *val = tokval;
            break;
        case TOKEN_VARIABLE:
        {
            if (token_peek(cxt, NULL, NULL) != '(')
            {
                // Really is a variable:
                *val = tokval;
                break;
            }
            // Otherwise this is a functor:
            var_t x = var(tokval);
            atom_t atom = make_atom(x->name, 0);
            if (!token_expect(cxt, '('))
            {
                ok = false;
                break;
            }
            args = (term_t *)gc_malloc(MAX_ARGS * sizeof(term_t));
            uint_t a = 0;
            if (token_peek(cxt, NULL, NULL) == ')')
                token_get(cxt, NULL, NULL);
            else
            {
                while (true)
                {
                    ok = parse_term_op(cxt, &tokval, UINT32_MAX);
                    if (!ok)
                        break;
                    if (a >= MAX_ARGS)
                    {
                        parse_error(cxt, "too many arguments; maximum is %zu",
                            MAX_ARGS);
                        ok = false;
                        break;
                    }
                    args[a++] = tokval;
                    tok = token_get(cxt, NULL, tokstr);
                    if (tok == ',')
                        continue;
                    if (tok == ')')
                        break;
                    parse_error(cxt, "expected token `,' or `)'; got token "
                        "`%s'", tokstr);
                    ok = false;
                    break;
                }
                if (!ok)
                    break;
            }
            atom = atom_set_arity(atom, a);
            func_t f = make_func_a(atom, args);
            tokval = term_func(f);
            *val = tokval;
            break;
        }
        default:
            if (tok != TOKEN_ERROR)
                parse_error(cxt, "unexpected token `%s'", tokstr);
            ok = false;
            break;
    }
    gc_free(tokstr);
    gc_free(args);
    return ok;
}