aboutsummaryrefslogtreecommitdiffstats
path: root/src/frontend/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/parser.c')
-rw-r--r--src/frontend/parser.c79
1 files changed, 53 insertions, 26 deletions
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;