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.c93
1 files changed, 79 insertions, 14 deletions
diff --git a/src/frontend/parser.c b/src/frontend/parser.c
index 3e4e449..45752e7 100644
--- a/src/frontend/parser.c
+++ b/src/frontend/parser.c
@@ -2,13 +2,42 @@
#define PARSER_C PARSER_C
#include <parser.h>
+struct AST* parse_source(struct Translation_Data *translation_data)
+{
+ return (struct AST*)parse_translation_unit(translation_data);
+}
/*
- * parse-unit: machine
- *
+ * translation-unit: (machine)*
*/
-struct AST* parse_unit(struct Translation_Data *translation_data)
+struct AST_Translation_Unit* parse_translation_unit(struct Translation_Data *translation_data)
{
- return (struct AST*)parse_machine(translation_data);
+ struct Queue *machines;
+ struct Map *hold_command_map;
+ struct AST_Machine *hold_machine;
+
+ machines=calloc(1,sizeof(struct Queue));
+ hold_command_map=malloc(sizeof(struct Map));
+ Map_Init(hold_command_map);
+
+ translation_data->hold_command_map=hold_command_map;
+
+ while(!get_and_check(translation_data,KW_EOF))
+ {
+ hold_machine=parse_machine(translation_data);
+ if(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;
+ }
+ }
+ return get_ast_translation_unit(machines,hold_command_map);
}
/*
* machine: 'machine' id '[' machine-inner ']' ';'
@@ -365,12 +394,17 @@ struct AST_Command* parse_command(struct Translation_Data *translation_data)
{
struct token *id;
struct token *string=NULL;
+ struct AST_Command *ret;
+
if(get_kw(translation_data)==KW_ID)
{
id=Queue_Pop(translation_data->tokens);
if(get_kw(translation_data)==KW_STRING)
string=Queue_Pop(translation_data->tokens);
- return get_ast_command(id,string);
+ ret=get_ast_command(id,string);
+ Map_Push(translation_data->hold_command_map,ret->argument->data,ret->argument->size,ret);
+
+ return ret;
}else
{
push_parsing_error("expected command id",translation_data);
@@ -406,8 +440,8 @@ struct AST_State* get_ast_state(struct token *id)
struct AST_State *ret;
ret=malloc(sizeof(struct AST_State));
- ret->type=AST_TYPE_STATE;
- ret->id=id;
+ ret->name=id;
+ /*number is assigned in get_ast_states*/
return ret;
}
@@ -416,8 +450,8 @@ struct AST_Event* get_ast_event(struct token *id)
struct AST_Event *ret;
ret=malloc(sizeof(struct AST_Event));
- ret->type=AST_TYPE_EVENT;
- ret->id=id;
+
+ ret->name=id;
return ret;
}
@@ -439,8 +473,9 @@ struct AST_States* get_ast_states(struct Queue *states)
while(states->size>0)
{
hold_state=Queue_Pop(states);
- Map_Push(ret->states_map,hold_state->id->data,hold_state->id->size,hold_state);
+ 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;
}
assert(states->size==0);
@@ -466,7 +501,7 @@ struct AST_Events* get_ast_events(struct Queue *events)
while(events->size>0)
{
hold_event=Queue_Pop(events);
- Map_Push(ret->events_map,hold_event->id->data,hold_event->id->size,hold_event);
+ Map_Push(ret->events_map,hold_event->name->data,hold_event->name->size,hold_event);
ret->events[events->size]=hold_event;
}
@@ -574,7 +609,7 @@ void delete_ast(struct AST* ast)
void delete_ast_event(struct AST_Event* ast)
{
if(ast==NULL)return;
- delete_token(ast->id);
+ delete_token(ast->name);
free(ast);
}
void delete_ast_states(struct AST_States* ast)
@@ -639,8 +674,8 @@ void delete_ast_transitions(struct AST_Transitions* ast)
void delete_ast_state(struct AST_State* ast)
{
if(ast==NULL)return;
- if(ast->id!=NULL)
- delete_token(ast->id);
+ if(ast->name!=NULL)
+ delete_token(ast->name);
free(ast);
}
void pointer_array_fill(void **array,struct Queue *q)
@@ -666,4 +701,34 @@ struct Queue* parse_list(struct AST *(*parser)(struct Translation_Data*),struct
return q;
}
+void delete_ast_translation_unit(struct AST_Translation_Unit *ast)
+{
+ size_t i;
+ Map_Map(ast->used_commands_map,(void (*)(void*))delete_ast_command);
+ Map_Destroy(ast->used_commands_map);
+ for(i=0;i<ast->number_of_machines;++i)
+ {
+ delete_ast_machine(ast->machines[i]);
+ }
+ free(ast->used_commands_map);
+ free(ast);
+}
+struct AST_Translation_Unit* get_ast_translation_unit(struct Queue *machines,struct Map *command_map)
+{
+ struct AST_Translation_Unit *ret;
+ struct AST_Machine *hold_machine;
+
+ ret=malloc(sizeof(struct AST_Translation_Unit)+sizeof(struct AST_Machine *[machines->size]));
+ ret->type=AST_TYPE_TRANSLATION_UNIT;
+ ret->used_commands_map=command_map;
+ ret->number_of_machines=machines->size;
+
+ while(machines->size>0)
+ {
+ hold_machine=Queue_Pop(machines);
+ ret->machines[machines->size]=hold_machine;
+ }
+
+ return ret;
+}
#endif