diff options
Diffstat (limited to 'src/frontend/parser.c')
-rw-r--r-- | src/frontend/parser.c | 56 |
1 files changed, 48 insertions, 8 deletions
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*/ |