From c875f8795586056a676e8a643a44211041ce44d2 Mon Sep 17 00:00:00 2001 From: Galin Simeonov Date: Fri, 4 Jun 2021 22:49:33 +0300 Subject: various stuffs --- src/frontend/parser.c | 79 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 26 deletions(-) (limited to 'src/frontend/parser.c') diff --git a/src/frontend/parser.c b/src/frontend/parser.c index 7af7af2..b38776e 100644 --- a/src/frontend/parser.c +++ b/src/frontend/parser.c @@ -15,6 +15,7 @@ struct AST_Translation_Unit* parse_translation_unit(struct Translation_Data *tra struct Map *hold_command_map; struct Map *hold_machines_map; struct AST_Machine *hold_machine; + struct AST_Machine *hold_possible_duplicate; machines=calloc(1,sizeof(struct Queue)); @@ -29,18 +30,22 @@ struct AST_Translation_Unit* parse_translation_unit(struct Translation_Data *tra while(!get_and_check(translation_data,KW_EOF)) { hold_machine=parse_machine(translation_data); - /*TODO check for repeated machine ids*/ if(hold_machine) { - Map_Push(hold_machines_map,hold_machine->id->data,hold_machine->id->size,hold_machine); - Queue_Push(machines,hold_machine); + if(hold_possible_duplicate=Map_Check(hold_machines_map,hold_machine->id->data,hold_machine->id->size)) + { + push_error_with_token("duplicate machine name",hold_machine->id,translation_data); + push_error_with_token("conflicts with",hold_possible_duplicate->id,translation_data); + delete_ast_machine(hold_machine); + return NULL; + }else + { + Map_Push(hold_machines_map,hold_machine->id->data,hold_machine->id->size,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; } } @@ -64,7 +69,6 @@ struct AST_Machine* parse_machine(struct Translation_Data *translation_data) ret=(struct AST_Machine*)parse_machine_inner(hold_id,translation_data); if(has_new_errors(translation_data)) { - delete_ast_machine(ret); touch_errors(translation_data); return NULL; @@ -76,13 +80,11 @@ struct AST_Machine* parse_machine(struct Translation_Data *translation_data) else { push_parsing_error("';' expected after machine definition",translation_data); - delete_ast_machine(ret); return NULL; } }else { push_parsing_error("closing ']' expected",translation_data); - delete_ast_machine(ret); return NULL; } }else @@ -232,9 +234,6 @@ struct AST_Machine* parse_machine_inner(struct token *machine_id,struct Translat error_cleanup: push_parsing_error("in machine",translation_data); - if(states)delete_ast_states(states); - if(events)delete_ast_events(events); - if(transitions)delete_ast_transitions(transitions); return NULL; } /* @@ -255,7 +254,7 @@ struct AST_States* parse_states_inner(struct Translation_Data *translation_data) }else { - return get_ast_states(ids); + return get_ast_states(ids,translation_data); } } /* @@ -323,7 +322,7 @@ struct AST_Transitions* parse_transitions_inner(struct Translation_Data *transla } } /* - * transition: 'from' state_id 'to' state_id 'on' 'event' event_id [ 'execute' pipeline ] + * transition: 'from' state_id 'to' state_id 'on' 'event' event_id [ granted-part ] [ statement-part ] * */ struct AST_Transition* parse_transition(struct Translation_Data *translation_data,struct AST_States *states,struct AST_Events *events) @@ -333,6 +332,7 @@ struct AST_Transition* parse_transition(struct Translation_Data *translation_dat struct AST_State *hold_to; struct AST_Event *hold_event; struct AST *hold_statement=NULL; + struct AST *hold_granted=NULL; struct token *hold_token; if(get_and_check(translation_data,KW_FROM)) @@ -361,12 +361,13 @@ struct AST_Transition* parse_transition(struct Translation_Data *translation_dat delete_token(hold_token); if(hold_event!=NULL) { - + hold_granted=parse_transition_granted(translation_data,states,events); + if(!get_and_check(translation_data,KW_SEMI_COLUMN) && (hold_statement=parse_statement(translation_data,states,events))==NULL) { push_parsing_error("in statement of transition",translation_data); return NULL; } /*GOAL!!!!!*/ - return get_ast_transition(hold_from,hold_to,hold_event,hold_statement); + return get_ast_transition(hold_from,hold_to,hold_event,hold_granted,hold_statement); }else { push_parsing_error("event not defined",translation_data); return NULL; } }else { push_parsing_error("no event name given in transition",translation_data); return NULL; } }else { push_parsing_error("expected 'on event'",translation_data); return NULL; } @@ -378,6 +379,20 @@ struct AST_Transition* parse_transition(struct Translation_Data *translation_dat }else { return NULL; } } +/* + * granted-part : 'granted' expression + */ +struct AST* parse_transition_granted(struct Translation_Data *translation_data,struct AST_States *states,struct AST_Events *events) +{ + if(get_and_check(translation_data,KW_GRANTED)) + { + return parse_expression(translation_data); + }else + { + return NULL; + } +} + /* * statement : 'execute' pipeline ; | 'if' expression statement [ else statement ] */ @@ -396,7 +411,6 @@ struct AST* parse_statement(struct Translation_Data *translation_data,struct AST }else { push_parsing_error("expected ';' at the end of pipeline",translation_data); - delete_ast(hold_body); return NULL; } }else if(get_and_check(translation_data,KW_IF)) @@ -411,8 +425,6 @@ struct AST* parse_statement(struct Translation_Data *translation_data,struct AST if(hold_else==NULL) { push_parsing_error("expected a statement after else",translation_data); - delete_ast(hold_expression); - delete_ast(hold_body); return NULL; } } @@ -420,8 +432,6 @@ struct AST* parse_statement(struct Translation_Data *translation_data,struct AST }else { push_parsing_error("expected body statement in if",translation_data); - if(hold_expression) - delete_ast(hold_expression); return NULL; } }else @@ -520,7 +530,7 @@ struct AST_Event* get_ast_event(struct token *id) return ret; } -struct AST_States* get_ast_states(struct Queue *states) +struct AST_States* get_ast_states(struct Queue *states,struct Translation_Data *translation_data) { struct AST_States *ret; struct AST_State *hold_state; @@ -538,8 +548,24 @@ struct AST_States* get_ast_states(struct Queue *states) while(states->size>0) { hold_state=Queue_Pop(states); - /*TODO check for redeclaration*/ - Map_Push(ret->states_map,hold_state->name->data,hold_state->name->size,hold_state); + + if(Map_Check(ret->states_map,hold_state->name->data,hold_state->name->size)) + { + size_t i; + + push_error_with_token("duplicate state in states definition",hold_state->name,translation_data); + + for(i=states->size+1;inumber_of_states;++i) + delete_ast_state(ret->states[i]); + delete_ast_state(hold_state); + while(states->size>0) + delete_ast_state(Queue_Pop(states)); + + return NULL; + }else + { + 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; @@ -578,7 +604,7 @@ struct AST_Events* get_ast_events(struct Queue *events) return ret; } -struct AST_Transition* get_ast_transition(struct AST_State *from,struct AST_State *to,struct AST_Event *event,struct AST *statement) +struct AST_Transition* get_ast_transition(struct AST_State *from,struct AST_State *to,struct AST_Event *event,struct AST *granted,struct AST *statement) { struct AST_Transition *ret; ret=malloc(sizeof(struct AST_Transition)); @@ -586,6 +612,7 @@ struct AST_Transition* get_ast_transition(struct AST_State *from,struct AST_Stat ret->from=from; ret->to=to; ret->event=event; + ret->granted=granted; ret->statement=statement; return ret; -- cgit v1.2.3