コード例 #1
0
ファイル: parser_rewind.cpp プロジェクト: upcaste/upcaste
    LIBUPCOREAPI
    int parser_rewind(parser* par) noexcept {
        if (!par) {
            return sexp_badarg;
        }
        else if (!par->loaded) {
            return sexp_badstate;
        }

        allocator* const alloc = par->alloc;
        assert(alloc);

        slist_clear<parser_token_block, &parser_token_block::node>(&par->open_stack, alloc);
        slist_clear<parser_token_block, &parser_token_block::node>(&par->unread_stack, alloc);

        verify(sexp_success == lexer_rewind(&par->lex));
        par->prev_column = 0;
        par->prev_line = 0;
        par->error_count = 0;
        par->warning_count = 0;
        return sexp_success;
    }
コード例 #2
0
ファイル: parser.c プロジェクト: bieber/col
// Parses a set of constant arguments
struct list *parse_constant_args(struct lexer_state *lexer, 
                                 enum token_type close)
{
    struct value *arg = NULL;
    struct list *args = list_new();
    
    // First check for empty list
    lex(lexer);
    
    if(lexer->error == UNRECOGNIZED_TOKEN)
    {
        print_error(lexer, LEX_ERROR);
        clear_value_list(args);
        return NULL;
    }
    
    if(lexer->error == END_OF_INPUT)
    {
        print_error(lexer, UNEXPECTED_END);
        clear_value_list(args);
        return NULL;
    }

    // If we already have close token, just return empty list
    if(lexer->type == close)
        return args;
    else
        lexer_rewind(lexer);

    while(lexer->error == OK)
    {        
        // First parse a value and add it to the list
        arg = parse_constant(lexer);

        if(!arg)
        {
            clear_function_list(args);
            return NULL;
        }

        list_push_back(args, arg);

        // Now checking for a separator or end of the list
        lex(lexer);

        if(lexer->error == UNRECOGNIZED_TOKEN)
        {
            print_error(lexer, LEX_ERROR);
            clear_value_list(args);
            return NULL;
        }

        if(lexer->error == END_OF_INPUT)
        {
            print_error(lexer, UNEXPECTED_END);
            clear_value_list(args);
            return NULL;
        }

        if(lexer->type == close)
            break;

        // If the list is still open, we expect a separator
        if(lexer->type != SEPARATOR)
        {
            print_error(lexer, INVALID_ELEMENT);
            clear_value_list(args);
            return NULL;
        }
    }

    return args;
}
コード例 #3
0
ファイル: parser.c プロジェクト: bieber/col
// Parses a function definition
struct function *parse_function(struct lexer_state *lexer)
{
    int error = 0;
    int i = 0;
    struct function *function = NULL;

    // First getting the identifier
    lex(lexer);

    if(lexer->error == UNRECOGNIZED_TOKEN)
    {
        print_error(lexer, LEX_ERROR);
        return NULL;
    }
    
    if(lexer->error == END_OF_INPUT)
    {
        print_error(lexer, UNEXPECTED_END);
        return NULL;
    }

    if(lexer->type != IDENT)
    {
        print_error(lexer, EXPECTED_IDENT);
        return NULL;
    }

    // Storing the identifier
    function = function_new();
    function->name = strdup(lexer->value.sval);

    // Figuring out what type of function this is
    function->type = USER; // Until proven otherwise

    // Checking against primitive and form lists
    for(i = 0; *(PRIMITIVE_FUNCTION_NAMES[i]); i++)
    {
        if(!strcmp(PRIMITIVE_FUNCTION_NAMES[i], function->name))
        {
            function->type = PRIMITIVE;
            function->index = i;
        }
    }
    
    for(i = 0; *(FUNCTIONAL_FORM_NAMES[i]); i++)
    {
        if(!strcmp(FUNCTIONAL_FORM_NAMES[i], function->name))
        {
            function->type = FORM;
            function->index = i;
        }
    }

    // Now checking for possible arguments
    if(function->type == PRIMITIVE)
    {
        lex(lexer);
        
        if(lexer->error == UNRECOGNIZED_TOKEN)
        {
            print_error(lexer, LEX_ERROR);
            function_delete(function);
            return NULL;
        }

        // Now checking for opening paren
        if(lexer->error == OK && lexer->type == OPEN_SPEC)
        {
            function->args = parse_constant_args(lexer, CLOSE_SPEC);
            if(!function->args)
            {
                function_delete(function);
                return NULL;
            }
        }
        else
        {
            lexer_rewind(lexer);
        }
    }
    else if(function->type == FORM)
    {
        // A functional form requires arguments
        if(!require_token(lexer, OPEN_FORM))
        {
            print_error(lexer, EXPECTED_ARGS);
            function_delete(function);
            return NULL;
        }

        function->args = parse_function_args(lexer);
        if(!function->args)
        {
            function_delete(function);
            return NULL;
        }
    }
    
    return function;
}