From fbb038282af00eb09bc5a8ef7a0e7a7b76998683 Mon Sep 17 00:00:00 2001 From: Galin Simeonov Date: Wed, 14 Jul 2021 01:43:40 +0300 Subject: added ability to attach statements to entry and exit of a given state --- src/backend/targets/C/ast_to_c.c | 5 +++- src/backend/targets/print/print.c | 6 +++++ src/frontend/lexer.c | 4 +++ src/frontend/lexer.h | 2 ++ src/frontend/parser.c | 56 +++++++++++++++++++++++++++++++++------ src/frontend/parser.h | 6 +++-- 6 files changed, 68 insertions(+), 11 deletions(-) diff --git a/src/backend/targets/C/ast_to_c.c b/src/backend/targets/C/ast_to_c.c index 9b8f95c..cd01e67 100644 --- a/src/backend/targets/C/ast_to_c.c +++ b/src/backend/targets/C/ast_to_c.c @@ -209,7 +209,9 @@ void ast_transitions_of_state_to_c(FILE *out,struct AST_Machine *machine,struct if(vector->number_of_transitions>0) { - fprintf(out,"\n\t%smachine_states_lock=1;\n",context_arrow); + fprintf(out,"\n\t%smachine_states_lock=1;\n\n",context_arrow); + ast_statement_to_c(out,1,vector->state->on_exit_statement,options); + fprintf(out,"\n"); fprintf(out,"\tswitch(event)\n\t{\n"); for(i=0;inumber_of_transitions;++i) { @@ -227,6 +229,7 @@ void ast_transitions_of_state_to_c(FILE *out,struct AST_Machine *machine,struct //ast_pipeline_to_c(out,3,vector->transitions[i]->pipeline); ast_statement_to_c(out,indentation,vector->transitions[i]->statement,options); + ast_statement_to_c(out,indentation,vector->transitions[i]->to->on_entry_statement,options); ast_to_c_print_tabs(out,indentation); fprintf(out,"%smachine_states[",context_arrow); ast_token_to_c(out,machine->id); diff --git a/src/backend/targets/print/print.c b/src/backend/targets/print/print.c index cfe22e9..162031f 100644 --- a/src/backend/targets/print/print.c +++ b/src/backend/targets/print/print.c @@ -90,6 +90,12 @@ void print_keyword_enum(enum Keyword code) case KW_GRANTED: printf("KW_GRANTED"); break; + case KW_ENTERING: + printf("KW_ENTERING"); + break; + case KW_EXITING: + printf("KW_EXITING"); + break; default: printf("LEXERROR"); } diff --git a/src/frontend/lexer.c b/src/frontend/lexer.c index 2d9bddd..10bb1c4 100644 --- a/src/frontend/lexer.c +++ b/src/frontend/lexer.c @@ -75,6 +75,10 @@ struct token* lex_step(struct Source *src,struct Translation_Data *translation_d 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); + if(check_and_move_if_on_word("entering",sizeof("entering")-1,src,1)) + return get_token(src->src+src->where_in_src-sizeof("entering")+1,sizeof("entering")-1,KW_ENTERING,src->current_row,src->current_column); + if(check_and_move_if_on_word("exiting",sizeof("exiting")-1,src,1)) + return get_token(src->src+src->where_in_src-sizeof("exiting")+1,sizeof("exiting")-1,KW_EXITING,src->current_row,src->current_column); diff --git a/src/frontend/lexer.h b/src/frontend/lexer.h index 1134739..995a807 100644 --- a/src/frontend/lexer.h +++ b/src/frontend/lexer.h @@ -38,6 +38,8 @@ enum Keyword KW_IF, KW_ELSE, KW_GRANTED, + KW_ENTERING, + KW_EXITING, }; struct token { diff --git a/src/frontend/parser.c b/src/frontend/parser.c index b38776e..4e370c0 100644 --- a/src/frontend/parser.c +++ b/src/frontend/parser.c @@ -258,15 +258,51 @@ struct AST_States* parse_states_inner(struct Translation_Data *translation_data) } } /* - * state : id + * state : id [ '[' ( 'on' 'entering' statement | 'on 'exiting' statement )* ']' ] * */ struct AST_State* parse_state(struct Translation_Data *translation_data) { + struct token *hold_id; + struct AST *hold_entry=NULL; + struct AST *hold_exit=NULL; + int i; + if(get_kw(translation_data)==KW_ID) - return get_ast_state(Queue_Pop(translation_data->tokens)); - else + { + hold_id=Queue_Pop(translation_data->tokens); + + if(get_and_check(translation_data,KW_OPEN_SQUARE)) + { + for(i=0;i<2;++i) + if(get_and_check(translation_data,KW_ON)) + { + if(get_and_check(translation_data,KW_ENTERING)) + hold_entry=parse_statement(translation_data); + else if(get_and_check(translation_data,KW_EXITING)) + hold_exit=parse_statement(translation_data); + else + break; + } + if(get_and_check(translation_data,KW_CLOSE_SQUARE)) + { + }else + { + if(hold_entry) + delete_ast(hold_entry); + if(hold_exit) + delete_ast(hold_exit); + delete_token(hold_id); + push_parsing_error("missing closing ']' in state definition",translation_data); + return NULL; + } + + } + return get_ast_state(hold_id,hold_entry,hold_exit); + }else + { return NULL; + } } /* * events-inner: id (, id)* @@ -363,7 +399,7 @@ struct AST_Transition* parse_transition(struct Translation_Data *translation_dat { 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) + if(!get_and_check(translation_data,KW_SEMI_COLUMN) && (hold_statement=parse_statement(translation_data))==NULL) { push_parsing_error("in statement of transition",translation_data); return NULL; } /*GOAL!!!!!*/ @@ -396,7 +432,7 @@ struct AST* parse_transition_granted(struct Translation_Data *translation_data,s /* * 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) +struct AST* parse_statement(struct Translation_Data *translation_data) { struct AST *hold_expression; struct AST *hold_body; @@ -416,12 +452,12 @@ struct AST* parse_statement(struct Translation_Data *translation_data,struct AST }else if(get_and_check(translation_data,KW_IF)) { hold_expression=parse_expression(translation_data); - hold_body=parse_statement(translation_data,states,events); + hold_body=parse_statement(translation_data); if(hold_body) { if(get_and_check(translation_data,KW_ELSE)) { - hold_else=parse_statement(translation_data,states,events); + hold_else=parse_statement(translation_data); if(hold_else==NULL) { push_parsing_error("expected a statement after else",translation_data); @@ -507,13 +543,17 @@ struct AST_State* parse_start_on(struct Translation_Data *translation_data,struc }else { push_parsing_error("expected an identifier for starting state",translation_data); return NULL; } }else { push_parsing_error("expected 'on'",translation_data); return NULL; } } -struct AST_State* get_ast_state(struct token *id) +struct AST_State* get_ast_state(struct token *id,struct AST *entry,struct AST *exit) { struct AST_State *ret; + assert(entry==NULL || entry->type==AST_TYPE_COMMAND || entry->type==AST_TYPE_PIPELINE || entry->type==AST_TYPE_IF); + assert(exit==NULL || exit->type==AST_TYPE_COMMAND || exit->type==AST_TYPE_PIPELINE || exit->type==AST_TYPE_IF); ret=malloc(sizeof(struct AST_State)); ret->type=AST_TYPE_STATE; ret->name=id; + ret->on_entry_statement=entry; + ret->on_exit_statement=exit; /*number is assigned in get_ast_states*/ /*parent machine is determined in anotation stage*/ diff --git a/src/frontend/parser.h b/src/frontend/parser.h index 8845507..17e64e3 100644 --- a/src/frontend/parser.h +++ b/src/frontend/parser.h @@ -37,6 +37,8 @@ struct AST_State struct token *name; struct AST_Machine *parent; size_t number; + struct AST *on_entry_statement; + struct AST *on_exit_statement; }; struct AST_Event { @@ -138,7 +140,7 @@ struct AST_Transition* parse_transition(struct Translation_Data *translation_dat 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* parse_statement(struct Translation_Data *translation_data); struct AST_Pipeline* parse_pipeline(struct Translation_Data *translation_data); struct AST_Command* parse_command(struct Translation_Data *translation_data); @@ -150,7 +152,7 @@ struct AST* parse_and_expression(struct Translation_Data *translation_data); struct AST* parse_not_expression(struct Translation_Data *translation_data); struct AST* parse_primary_expression(struct Translation_Data *translation_data); -struct AST_State* get_ast_state(struct token *id); +struct AST_State* get_ast_state(struct token *id,struct AST *entry,struct AST *exit); struct AST_Event* get_ast_event(struct token *id); struct AST_States* get_ast_states(struct Queue *states,struct Translation_Data *translation_data); struct AST_Events* get_ast_events(struct Queue *events); -- cgit v1.2.3