MEGATRON



LOG | FILES | OVERVIEW


F diff --git a/src/backend/targets/C/ast_to_c.c b/src/backend/targets/C/ast_to_c.c --- a/src/backend/targets/C/ast_to_c.c +++ b/src/backend/targets/C/ast_to_c.c
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;i<vector->number_of_transitions;++i)
{
//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);
F diff --git a/src/backend/targets/print/print.c b/src/backend/targets/print/print.c --- a/src/backend/targets/print/print.c +++ b/src/backend/targets/print/print.c
case KW_GRANTED:
printf("KW_GRANTED");
break;
+ case KW_ENTERING:
+ printf("KW_ENTERING");
+ break;
+ case KW_EXITING:
+ printf("KW_EXITING");
+ break;
default:
printf("LEXERROR");
}
F diff --git a/src/frontend/lexer.c b/src/frontend/lexer.c --- a/src/frontend/lexer.c +++ b/src/frontend/lexer.c
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);
F diff --git a/src/frontend/lexer.h b/src/frontend/lexer.h --- a/src/frontend/lexer.h +++ b/src/frontend/lexer.h
KW_IF,
KW_ELSE,
KW_GRANTED,
+ KW_ENTERING,
+ KW_EXITING,
};
struct token
{
F diff --git a/src/frontend/parser.c b/src/frontend/parser.c --- a/src/frontend/parser.c +++ b/src/frontend/parser.c
}
}
/*
- * 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)*
{
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!!!!!*/
/*
* 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;
}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);
}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*/
F diff --git a/src/frontend/parser.h b/src/frontend/parser.h --- a/src/frontend/parser.h +++ b/src/frontend/parser.h
struct token *name;
struct AST_Machine *parent;
size_t number;
+ struct AST *on_entry_statement;
+ struct AST *on_exit_statement;
};
struct AST_Event
{
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);
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);