diff options
author | Galin Simeonov <gts@volconst.com> | 2021-06-04 22:49:33 +0300 |
---|---|---|
committer | Galin Simeonov <gts@volconst.com> | 2021-07-15 18:07:29 +0300 |
commit | c875f8795586056a676e8a643a44211041ce44d2 (patch) | |
tree | 88bfd4b4923ed30de31b130672dda65e4b18a607 /src/frontend | |
parent | a26684a417729699e95b335a3d00798237ffba9b (diff) | |
download | MEGATRON-c875f8795586056a676e8a643a44211041ce44d2.tar.gz |
various stuffs
Diffstat (limited to 'src/frontend')
-rw-r--r-- | src/frontend/lexer.c | 3 | ||||
-rw-r--r-- | src/frontend/lexer.h | 1 | ||||
-rw-r--r-- | src/frontend/parser.c | 79 | ||||
-rw-r--r-- | src/frontend/parser.h | 7 |
4 files changed, 61 insertions, 29 deletions
diff --git a/src/frontend/lexer.c b/src/frontend/lexer.c index a832a17..2d9bddd 100644 --- a/src/frontend/lexer.c +++ b/src/frontend/lexer.c @@ -71,9 +71,10 @@ struct token* lex_step(struct Source *src,struct Translation_Data *translation_d return get_token(src->src+src->where_in_src-sizeof("transitions")+1,sizeof("transitions")-1,KW_TRANSITIONS,src->current_row,src->current_column); if(check_and_move_if_on_word("if",sizeof("if")-1,src,1)) return get_token(src->src+src->where_in_src-sizeof("if")+1,sizeof("if")-1,KW_IF,src->current_row,src->current_column); - if(check_and_move_if_on_word("else",sizeof("else")-1,src,1)) return get_token(src->src+src->where_in_src-sizeof("else")+1,sizeof("else")-1,KW_ELSE,src->current_row,src->current_column); + if(check_and_move_if_on_word("granted",sizeof("granted")-1,src,1)) + return get_token(src->src+src->where_in_src-sizeof("granted")+1,sizeof("granted")-1,KW_GRANTED,src->current_row,src->current_column); diff --git a/src/frontend/lexer.h b/src/frontend/lexer.h index 54c88fa..1134739 100644 --- a/src/frontend/lexer.h +++ b/src/frontend/lexer.h @@ -37,6 +37,7 @@ enum Keyword KW_NOT, KW_IF, KW_ELSE, + KW_GRANTED, }; struct token { 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; } @@ -379,6 +380,20 @@ struct AST_Transition* parse_transition(struct Translation_Data *translation_dat } /* + * 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 ] */ struct AST* parse_statement(struct Translation_Data *translation_data,struct AST_States *states,struct AST_Events *events) @@ -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;i<ret->number_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; diff --git a/src/frontend/parser.h b/src/frontend/parser.h index 4745f63..8845507 100644 --- a/src/frontend/parser.h +++ b/src/frontend/parser.h @@ -62,6 +62,7 @@ struct AST_Transition struct AST_State *from; struct AST_State *to; struct AST_Event *event; + struct AST *granted; struct AST *statement; }; struct AST_Command @@ -135,6 +136,8 @@ struct AST_Event* parse_event(struct Translation_Data *translation_data); struct AST_Transitions* parse_transitions_inner(struct Translation_Data *translation_data,struct AST_States *states,struct AST_Events *events ); struct AST_Transition* parse_transition(struct Translation_Data *translation_data,struct AST_States *states,struct AST_Events *events); +struct AST* parse_transition_granted(struct Translation_Data *translation_data,struct AST_States *states,struct AST_Events *events); + struct AST* parse_statement(struct Translation_Data *translation_data,struct AST_States *states,struct AST_Events *events); struct AST_Pipeline* parse_pipeline(struct Translation_Data *translation_data); @@ -149,9 +152,9 @@ struct AST* parse_primary_expression(struct Translation_Data *translation_data); struct AST_State* get_ast_state(struct token *id); struct AST_Event* get_ast_event(struct token *id); -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_Events* get_ast_events(struct Queue *events); -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_Command* get_ast_command(struct token *function_name,struct token *argument); 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); |