diff options
Diffstat (limited to 'src/frontend')
-rw-r--r-- | src/frontend/lexer.h | 2 | ||||
-rw-r--r-- | src/frontend/parser.c | 93 | ||||
-rw-r--r-- | src/frontend/parser.h | 26 |
3 files changed, 98 insertions, 23 deletions
diff --git a/src/frontend/lexer.h b/src/frontend/lexer.h index 320146c..d102540 100644 --- a/src/frontend/lexer.h +++ b/src/frontend/lexer.h @@ -32,8 +32,8 @@ enum Keyword }; struct token { - size_t size; enum Keyword type; + size_t size; char *data; size_t row; size_t column; diff --git a/src/frontend/parser.c b/src/frontend/parser.c index 3e4e449..45752e7 100644 --- a/src/frontend/parser.c +++ b/src/frontend/parser.c @@ -2,13 +2,42 @@ #define PARSER_C PARSER_C #include <parser.h> +struct AST* parse_source(struct Translation_Data *translation_data) +{ + return (struct AST*)parse_translation_unit(translation_data); +} /* - * parse-unit: machine - * + * translation-unit: (machine)* */ -struct AST* parse_unit(struct Translation_Data *translation_data) +struct AST_Translation_Unit* parse_translation_unit(struct Translation_Data *translation_data) { - return (struct AST*)parse_machine(translation_data); + struct Queue *machines; + struct Map *hold_command_map; + struct AST_Machine *hold_machine; + + machines=calloc(1,sizeof(struct Queue)); + hold_command_map=malloc(sizeof(struct Map)); + Map_Init(hold_command_map); + + translation_data->hold_command_map=hold_command_map; + + while(!get_and_check(translation_data,KW_EOF)) + { + hold_machine=parse_machine(translation_data); + if(hold_machine) + { + Queue_Push(machines,hold_machine); + } + else + { + Map_Map(hold_command_map,(void (*)(void*))delete_ast_command); + Map_Destroy(hold_command_map); + while(machines->size>0) + delete_ast_machine(Queue_Pop(machines)); + return NULL; + } + } + return get_ast_translation_unit(machines,hold_command_map); } /* * machine: 'machine' id '[' machine-inner ']' ';' @@ -365,12 +394,17 @@ struct AST_Command* parse_command(struct Translation_Data *translation_data) { struct token *id; struct token *string=NULL; + struct AST_Command *ret; + if(get_kw(translation_data)==KW_ID) { id=Queue_Pop(translation_data->tokens); if(get_kw(translation_data)==KW_STRING) string=Queue_Pop(translation_data->tokens); - return get_ast_command(id,string); + ret=get_ast_command(id,string); + Map_Push(translation_data->hold_command_map,ret->argument->data,ret->argument->size,ret); + + return ret; }else { push_parsing_error("expected command id",translation_data); @@ -406,8 +440,8 @@ struct AST_State* get_ast_state(struct token *id) struct AST_State *ret; ret=malloc(sizeof(struct AST_State)); - ret->type=AST_TYPE_STATE; - ret->id=id; + ret->name=id; + /*number is assigned in get_ast_states*/ return ret; } @@ -416,8 +450,8 @@ struct AST_Event* get_ast_event(struct token *id) struct AST_Event *ret; ret=malloc(sizeof(struct AST_Event)); - ret->type=AST_TYPE_EVENT; - ret->id=id; + + ret->name=id; return ret; } @@ -439,8 +473,9 @@ struct AST_States* get_ast_states(struct Queue *states) while(states->size>0) { hold_state=Queue_Pop(states); - Map_Push(ret->states_map,hold_state->id->data,hold_state->id->size,hold_state); + Map_Push(ret->states_map,hold_state->name->data,hold_state->name->size,hold_state); ret->states[states->size]=hold_state; + hold_state->number=states->size; } assert(states->size==0); @@ -466,7 +501,7 @@ struct AST_Events* get_ast_events(struct Queue *events) while(events->size>0) { hold_event=Queue_Pop(events); - Map_Push(ret->events_map,hold_event->id->data,hold_event->id->size,hold_event); + Map_Push(ret->events_map,hold_event->name->data,hold_event->name->size,hold_event); ret->events[events->size]=hold_event; } @@ -574,7 +609,7 @@ void delete_ast(struct AST* ast) void delete_ast_event(struct AST_Event* ast) { if(ast==NULL)return; - delete_token(ast->id); + delete_token(ast->name); free(ast); } void delete_ast_states(struct AST_States* ast) @@ -639,8 +674,8 @@ void delete_ast_transitions(struct AST_Transitions* ast) void delete_ast_state(struct AST_State* ast) { if(ast==NULL)return; - if(ast->id!=NULL) - delete_token(ast->id); + if(ast->name!=NULL) + delete_token(ast->name); free(ast); } void pointer_array_fill(void **array,struct Queue *q) @@ -666,4 +701,34 @@ struct Queue* parse_list(struct AST *(*parser)(struct Translation_Data*),struct return q; } +void delete_ast_translation_unit(struct AST_Translation_Unit *ast) +{ + size_t i; + Map_Map(ast->used_commands_map,(void (*)(void*))delete_ast_command); + Map_Destroy(ast->used_commands_map); + for(i=0;i<ast->number_of_machines;++i) + { + delete_ast_machine(ast->machines[i]); + } + free(ast->used_commands_map); + free(ast); +} +struct AST_Translation_Unit* get_ast_translation_unit(struct Queue *machines,struct Map *command_map) +{ + struct AST_Translation_Unit *ret; + struct AST_Machine *hold_machine; + + ret=malloc(sizeof(struct AST_Translation_Unit)+sizeof(struct AST_Machine *[machines->size])); + ret->type=AST_TYPE_TRANSLATION_UNIT; + ret->used_commands_map=command_map; + ret->number_of_machines=machines->size; + + while(machines->size>0) + { + hold_machine=Queue_Pop(machines); + ret->machines[machines->size]=hold_machine; + } + + return ret; +} #endif diff --git a/src/frontend/parser.h b/src/frontend/parser.h index ef82184..eaede84 100644 --- a/src/frontend/parser.h +++ b/src/frontend/parser.h @@ -7,6 +7,7 @@ enum AST_Type { + AST_TYPE_TRANSLATION_UNIT, AST_TYPE_MACHINE, AST_TYPE_STATE, AST_TYPE_STATES, @@ -23,13 +24,12 @@ struct AST }; struct AST_State { - enum AST_Type type; - struct token *id; + struct token *name; + size_t number; }; struct AST_Event { - enum AST_Type type; - struct token *id; + struct token *name; }; struct AST_States { @@ -65,6 +65,12 @@ struct AST_Pipeline size_t size; struct AST_Command *pipeline[]; }; +struct AST_Transitions +{ + enum AST_Type type; + size_t size; + struct AST_Transition *transitions[]; +}; struct AST_Machine { enum AST_Type type; @@ -73,15 +79,17 @@ struct AST_Machine struct AST_Events *events; struct AST_Transitions *transitions; }; -struct AST_Transitions +struct AST_Translation_Unit { enum AST_Type type; - size_t size; - struct AST_Transition *transitions[]; + struct Map *used_commands_map; + size_t number_of_machines; + struct AST_Machine *machines[]; }; -struct AST* parse_unit(struct Translation_Data *translation_data); +struct AST* parse_source(struct Translation_Data *translation_data); +struct AST_Translation_Unit* parse_translation_unit(struct Translation_Data *translation_data); struct AST_Machine* parse_machine(struct Translation_Data *translation_data); struct AST_Machine* parse_machine_inner(struct token *machine_id,struct Translation_Data *translation_data); struct AST_States* parse_states_inner(struct Translation_Data *translation_data); @@ -104,6 +112,7 @@ struct AST_Command* get_ast_command(struct token *function_name,struct token *ar struct AST_Pipeline* get_ast_pipeline(struct Queue *pipeline); struct AST_Machine* get_ast_machine(struct token *id,struct AST_States *states,struct AST_Events *events,struct AST_Transitions *transitions,struct AST_State *starting_state); struct AST_Transitions* get_ast_transitions(struct Queue *transitions); +struct AST_Translation_Unit* get_ast_translation_unit(struct Queue *machines,struct Map *command_map); void delete_ast(struct AST* ast); @@ -116,6 +125,7 @@ void delete_ast_command(struct AST_Command* ast); void delete_ast_pipeline(struct AST_Pipeline* ast); void delete_ast_machine(struct AST_Machine* ast); void delete_ast_transitions(struct AST_Transitions* ast); +void delete_ast_translation_unit(struct AST_Translation_Unit *ast); void pointer_array_fill(void **array,struct Queue *q); |