Rename *_yacc_* to *_parse_*
This commit is contained in:
parent
8e454b3d5a
commit
4387f9d39a
130
src/rjp_parse.c
130
src/rjp_parse.c
@ -30,26 +30,26 @@
|
||||
|
||||
#define RJP_INITIAL_PARSE_DEPTH 16
|
||||
|
||||
typedef enum RJP_yacc_target{
|
||||
rjp_yacc_end,
|
||||
rjp_yacc_start,
|
||||
rjp_yacc_first_mem_key,
|
||||
rjp_yacc_mem_key,
|
||||
rjp_yacc_arr_first_value,
|
||||
rjp_yacc_arr_value,
|
||||
rjp_yacc_arr_comma,
|
||||
rjp_yacc_key_colon,
|
||||
rjp_yacc_obj_value,
|
||||
rjp_yacc_obj_comma
|
||||
}RJP_yacc_target;
|
||||
typedef enum RJP_parse_target{
|
||||
rjp_parse_end,
|
||||
rjp_parse_start,
|
||||
rjp_parse_first_mem_key,
|
||||
rjp_parse_mem_key,
|
||||
rjp_parse_arr_first_value,
|
||||
rjp_parse_arr_value,
|
||||
rjp_parse_arr_comma,
|
||||
rjp_parse_key_colon,
|
||||
rjp_parse_obj_value,
|
||||
rjp_parse_obj_comma
|
||||
}RJP_parse_target;
|
||||
|
||||
typedef struct RJP_yacc_stack{
|
||||
RJP_yacc_target* stack;
|
||||
typedef struct RJP_parse_stack{
|
||||
RJP_parse_target* stack;
|
||||
RJP_index position;
|
||||
RJP_index size;
|
||||
}RJP_yacc_stack;
|
||||
typedef struct RJP_yacc_state{
|
||||
RJP_yacc_stack target_stack;
|
||||
}RJP_parse_stack;
|
||||
typedef struct RJP_parse_state{
|
||||
RJP_parse_stack target_stack;
|
||||
RJP_value* root;
|
||||
RJP_value* curr;
|
||||
RJP_value* lastadded;
|
||||
@ -57,41 +57,41 @@ typedef struct RJP_yacc_state{
|
||||
int row, column;
|
||||
const _Bool allow_comments;
|
||||
const _Bool allow_trail_comma;
|
||||
}RJP_yacc_state;
|
||||
}RJP_parse_state;
|
||||
|
||||
static void irjp_init_yacc_stack(RJP_yacc_stack* s){
|
||||
static void irjp_init_parse_stack(RJP_parse_stack* s){
|
||||
s->size = RJP_INITIAL_PARSE_DEPTH;
|
||||
s->stack = rjp_alloc(sizeof(RJP_yacc_target)*s->size);
|
||||
s->stack = rjp_alloc(sizeof(RJP_parse_target)*s->size);
|
||||
s->position = 0;
|
||||
s->stack[0] = rjp_yacc_start;
|
||||
s->stack[0] = rjp_parse_start;
|
||||
}
|
||||
static void irjp_delete_yacc_stack(RJP_yacc_stack* s){
|
||||
static void irjp_delete_parse_stack(RJP_parse_stack* s){
|
||||
rjp_free(s->stack);
|
||||
s->stack = NULL;
|
||||
}
|
||||
static void irjp_resize_yacc_stack(RJP_yacc_stack* s, RJP_index newsize){
|
||||
RJP_yacc_target* newstack = rjp_alloc(sizeof(RJP_yacc_target) * newsize);
|
||||
memcpy(newstack, s->stack, s->size*sizeof(RJP_yacc_target));
|
||||
static void irjp_resize_parse_stack(RJP_parse_stack* s, RJP_index newsize){
|
||||
RJP_parse_target* newstack = rjp_alloc(sizeof(RJP_parse_target) * newsize);
|
||||
memcpy(newstack, s->stack, s->size*sizeof(RJP_parse_target));
|
||||
rjp_free(s->stack);
|
||||
s->stack = newstack;
|
||||
s->size = newsize;
|
||||
}
|
||||
static void irjp_yacc_stack_push(RJP_yacc_stack* s, RJP_yacc_target target){
|
||||
static void irjp_parse_stack_push(RJP_parse_stack* s, RJP_parse_target target){
|
||||
if((s->position+1) == s->size)
|
||||
irjp_resize_yacc_stack(s, s->size*2);
|
||||
irjp_resize_parse_stack(s, s->size*2);
|
||||
s->stack[++s->position] = target;
|
||||
}
|
||||
static RJP_yacc_target irjp_yacc_stack_pop(RJP_yacc_stack* s){
|
||||
static RJP_parse_target irjp_parse_stack_pop(RJP_parse_stack* s){
|
||||
return s->stack[s->position--];
|
||||
}
|
||||
static RJP_yacc_target irjp_yacc_stack_current(RJP_yacc_stack* s){
|
||||
static RJP_parse_target irjp_parse_stack_current(RJP_parse_stack* s){
|
||||
return s->stack[s->position];
|
||||
}
|
||||
static void irjp_yacc_stack_set(RJP_yacc_stack* s, RJP_yacc_target target){
|
||||
static void irjp_parse_stack_set(RJP_parse_stack* s, RJP_parse_target target){
|
||||
s->stack[s->position] = target;
|
||||
}
|
||||
|
||||
static int irjp_init_value(RJP_value* newval, RJP_lex_category cat, RJP_yacc_state* state){
|
||||
static int irjp_init_value(RJP_value* newval, RJP_lex_category cat, RJP_parse_state* state){
|
||||
RJP_index length = state->lexstate.length;
|
||||
RJP_index offset = state->lexstate.offset;
|
||||
const char* str = state->lexstate.str + offset;
|
||||
@ -126,12 +126,12 @@ static int irjp_init_value(RJP_value* newval, RJP_lex_category cat, RJP_yacc_sta
|
||||
break;
|
||||
case rjp_lex_obrace:
|
||||
newval->type = rjp_json_object;
|
||||
irjp_yacc_stack_push(&state->target_stack, rjp_yacc_first_mem_key);
|
||||
irjp_parse_stack_push(&state->target_stack, rjp_parse_first_mem_key);
|
||||
state->curr = state->lastadded;
|
||||
break;
|
||||
case rjp_lex_obracket:
|
||||
newval->type = rjp_json_array;
|
||||
irjp_yacc_stack_push(&state->target_stack, rjp_yacc_arr_first_value);
|
||||
irjp_parse_stack_push(&state->target_stack, rjp_parse_arr_first_value);
|
||||
state->curr = state->lastadded;
|
||||
break;
|
||||
default:
|
||||
@ -139,13 +139,13 @@ static int irjp_init_value(RJP_value* newval, RJP_lex_category cat, RJP_yacc_sta
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
static RJP_value* irjp_add_value_to_array(RJP_lex_category cat, RJP_yacc_state* state){
|
||||
static RJP_value* irjp_add_value_to_array(RJP_lex_category cat, RJP_parse_state* state){
|
||||
state->lastadded = rjp_add_element(state->curr);
|
||||
if(irjp_init_value(state->lastadded, cat, state))
|
||||
return NULL;
|
||||
return state->lastadded;
|
||||
}
|
||||
static RJP_value* irjp_add_value_to_object(RJP_yacc_state* state, const char* key, RJP_index keylen){
|
||||
static RJP_value* irjp_add_value_to_object(RJP_parse_state* state, const char* key, RJP_index keylen){
|
||||
RJP_index newlen;
|
||||
char* newkey = irjp_convert_string(key, keylen, &newlen);
|
||||
return (state->lastadded = rjp_add_member(state->curr, newkey, newlen));
|
||||
@ -159,16 +159,16 @@ static RJP_lex_category irjp_convert_comment(_Bool allow_comments){
|
||||
return rjp_lex_invalid;
|
||||
}
|
||||
|
||||
static void irjp_init_parse_state(RJP_yacc_state* state, const char* str){
|
||||
static void irjp_init_parse_state(RJP_parse_state* state, const char* str){
|
||||
state->column = 1;
|
||||
state->row = 1;
|
||||
|
||||
irjp_init_yacc_stack(&state->target_stack);
|
||||
irjp_init_parse_stack(&state->target_stack);
|
||||
state->lexstate.str = str;
|
||||
state->root = state->curr = state->lastadded = rjp_calloc(1, sizeof(RJP_value));
|
||||
}
|
||||
static void irjp_delete_parse_state(RJP_yacc_state* state){
|
||||
irjp_delete_yacc_stack(&state->target_stack);
|
||||
static void irjp_delete_parse_state(RJP_parse_state* state){
|
||||
irjp_delete_parse_stack(&state->target_stack);
|
||||
rjp_free_value(state->root);
|
||||
state->root = NULL;
|
||||
}
|
||||
@ -181,7 +181,7 @@ static void irjp_delete_parse_state(RJP_yacc_state* state){
|
||||
return RJP_PARSE_STATUS_ERR; \
|
||||
}while(0)
|
||||
|
||||
static int irjp_parse_handle_lexcat(RJP_lex_category cat, RJP_yacc_state* state){
|
||||
static int irjp_parse_handle_lexcat(RJP_lex_category cat, RJP_parse_state* state){
|
||||
if(cat == rjp_lex_line_comment || cat == rjp_lex_block_comment)
|
||||
cat = irjp_convert_comment(state->allow_comments);
|
||||
|
||||
@ -195,23 +195,23 @@ static int irjp_parse_handle_lexcat(RJP_lex_category cat, RJP_yacc_state* state)
|
||||
if(cat == rjp_lex_invalid)
|
||||
irjp_parse_error("Invalid token");
|
||||
|
||||
switch(irjp_yacc_stack_current(&state->target_stack)){
|
||||
switch(irjp_parse_stack_current(&state->target_stack)){
|
||||
|
||||
case rjp_yacc_start:
|
||||
irjp_yacc_stack_set(&state->target_stack, rjp_yacc_end);
|
||||
case rjp_parse_start:
|
||||
irjp_parse_stack_set(&state->target_stack, rjp_parse_end);
|
||||
if(irjp_init_value(state->root, cat, state)){
|
||||
irjp_parse_error("Expected value");
|
||||
}
|
||||
break;
|
||||
case rjp_yacc_first_mem_key:
|
||||
case rjp_parse_first_mem_key:
|
||||
if(cat == rjp_lex_cbrace){
|
||||
irjp_yacc_stack_pop(&state->target_stack);
|
||||
irjp_parse_stack_pop(&state->target_stack);
|
||||
state->curr = state->curr->parent;
|
||||
}else{
|
||||
//fallthrough
|
||||
case rjp_yacc_mem_key:
|
||||
case rjp_parse_mem_key:
|
||||
if(cat == rjp_lex_string){
|
||||
irjp_yacc_stack_set(&state->target_stack, rjp_yacc_key_colon);
|
||||
irjp_parse_stack_set(&state->target_stack, rjp_parse_key_colon);
|
||||
if(!irjp_add_value_to_object(state, state->lexstate.str+state->lexstate.offset, state->lexstate.length)){
|
||||
irjp_parse_error("Expected member key");
|
||||
}
|
||||
@ -220,59 +220,59 @@ static int irjp_parse_handle_lexcat(RJP_lex_category cat, RJP_yacc_state* state)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case rjp_yacc_arr_first_value:
|
||||
case rjp_parse_arr_first_value:
|
||||
if(cat == rjp_lex_cbracket){
|
||||
irjp_yacc_stack_pop(&state->target_stack);
|
||||
irjp_parse_stack_pop(&state->target_stack);
|
||||
state->curr = state->curr->parent;
|
||||
}else{
|
||||
//fallthrough
|
||||
case rjp_yacc_arr_value:
|
||||
irjp_yacc_stack_set(&state->target_stack, rjp_yacc_arr_comma);
|
||||
case rjp_parse_arr_value:
|
||||
irjp_parse_stack_set(&state->target_stack, rjp_parse_arr_comma);
|
||||
if(!irjp_add_value_to_array(cat, state))
|
||||
irjp_parse_error("Expected value");
|
||||
}
|
||||
break;
|
||||
|
||||
case rjp_yacc_key_colon:
|
||||
case rjp_parse_key_colon:
|
||||
if(cat != rjp_lex_colon)
|
||||
irjp_parse_error("Expected member key");
|
||||
irjp_yacc_stack_set(&state->target_stack, rjp_yacc_obj_value);
|
||||
irjp_parse_stack_set(&state->target_stack, rjp_parse_obj_value);
|
||||
break;
|
||||
case rjp_yacc_obj_value:
|
||||
irjp_yacc_stack_set(&state->target_stack, rjp_yacc_obj_comma);
|
||||
case rjp_parse_obj_value:
|
||||
irjp_parse_stack_set(&state->target_stack, rjp_parse_obj_comma);
|
||||
if(irjp_init_value(state->lastadded, cat, state)){
|
||||
irjp_parse_error("Expected value");
|
||||
}
|
||||
break;
|
||||
case rjp_yacc_obj_comma:
|
||||
case rjp_parse_obj_comma:
|
||||
if(cat == rjp_lex_comma){
|
||||
irjp_yacc_stack_set(&state->target_stack, state->allow_trail_comma ? rjp_yacc_first_mem_key : rjp_yacc_mem_key);
|
||||
irjp_parse_stack_set(&state->target_stack, state->allow_trail_comma ? rjp_parse_first_mem_key : rjp_parse_mem_key);
|
||||
}else if(cat == rjp_lex_cbrace){
|
||||
irjp_yacc_stack_pop(&state->target_stack);
|
||||
irjp_parse_stack_pop(&state->target_stack);
|
||||
state->curr = state->curr->parent;
|
||||
}else{
|
||||
irjp_parse_error("Expected comma");
|
||||
}
|
||||
break;
|
||||
|
||||
case rjp_yacc_arr_comma:
|
||||
case rjp_parse_arr_comma:
|
||||
if(cat == rjp_lex_comma){
|
||||
irjp_yacc_stack_set(&state->target_stack, state->allow_trail_comma ? rjp_yacc_arr_first_value : rjp_yacc_arr_value);
|
||||
irjp_parse_stack_set(&state->target_stack, state->allow_trail_comma ? rjp_parse_arr_first_value : rjp_parse_arr_value);
|
||||
}else if(cat == rjp_lex_cbracket){
|
||||
irjp_yacc_stack_pop(&state->target_stack);
|
||||
irjp_parse_stack_pop(&state->target_stack);
|
||||
state->curr = state->curr->parent;
|
||||
}else{
|
||||
irjp_parse_error("Expected comma");
|
||||
}
|
||||
break;
|
||||
|
||||
case rjp_yacc_end:
|
||||
case rjp_parse_end:
|
||||
if(state->lexstate.str[state->lexstate.offset] != 0)
|
||||
irjp_parse_error("Excess data after end of JSON");
|
||||
};
|
||||
return RJP_PARSE_STATUS_SUC;
|
||||
}
|
||||
static int irjp_parse(RJP_yacc_state* state){
|
||||
static int irjp_parse(RJP_parse_state* state){
|
||||
RJP_lex_category cat;
|
||||
for(cat = irjp_lex(&state->lexstate);cat & rjp_lex_accept;cat = irjp_lex(&state->lexstate),state->row += state->lexstate.length){
|
||||
if(irjp_parse_handle_lexcat(cat, state) != RJP_PARSE_STATUS_SUC)
|
||||
@ -285,13 +285,13 @@ static int irjp_parse(RJP_yacc_state* state){
|
||||
irjp_parse_error("Invalid Token");
|
||||
}
|
||||
RJP_value* rjp_parse(const char* str, int flags){
|
||||
RJP_yacc_state state = {.allow_comments = (flags & RJP_PARSE_ALLOW_COMMENTS),
|
||||
RJP_parse_state state = {.allow_comments = (flags & RJP_PARSE_ALLOW_COMMENTS),
|
||||
.allow_trail_comma = (flags & RJP_PARSE_ALLOW_TRAILING_COMMA)
|
||||
};
|
||||
irjp_init_parse_state(&state, str);
|
||||
int status = irjp_parse(&state);
|
||||
if(status == RJP_PARSE_STATUS_SUC){
|
||||
irjp_delete_yacc_stack(&state.target_stack);
|
||||
irjp_delete_parse_stack(&state.target_stack);
|
||||
return state.root;
|
||||
}else{
|
||||
irjp_delete_parse_state(&state);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user