aboutsummaryrefslogtreecommitdiffstats
path: root/parser.c
diff options
context:
space:
mode:
authorGalin Simeonov <gts@volconst.com>2021-05-31 22:02:10 +0300
committerGalin Simeonov <gts@volconst.com>2021-07-15 18:00:15 +0300
commit255a49ba5a41b3854dbdfebdec75fb6229450507 (patch)
tree616ea5786cb91d03ef609d32b402941dc30e926b /parser.c
parentf768d9bdb84e846d89aac66a4f3433a44241c298 (diff)
downloadMEGATRON-255a49ba5a41b3854dbdfebdec75fb6229450507.tar.gz
added cmake file
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c669
1 files changed, 0 insertions, 669 deletions
diff --git a/parser.c b/parser.c
deleted file mode 100644
index 3e4e449..0000000
--- a/parser.c
+++ /dev/null
@@ -1,669 +0,0 @@
-#ifndef PARSER_C
-#define PARSER_C PARSER_C
-#include <parser.h>
-
-/*
- * parse-unit: machine
- *
- */
-struct AST* parse_unit(struct Translation_Data *translation_data)
-{
- return (struct AST*)parse_machine(translation_data);
-}
-/*
- * machine: 'machine' id '[' machine-inner ']' ';'
- *
- */
-struct AST_Machine* parse_machine(struct Translation_Data *translation_data)
-{
- struct AST_Machine *ret;
- struct token *hold_id;
- if(get_and_check(translation_data,KW_MACHINE))
- {
- if(get_kw(translation_data)==KW_ID)
- {
- hold_id=Queue_Pop(translation_data->tokens);
- if(get_and_check(translation_data,KW_OPEN_SQUARE))
- {
- 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;
- }
- if(get_and_check(translation_data,KW_CLOSE_SQUARE))
- {
- if(get_and_check(translation_data,KW_SEMI_COLUMN))
- return ret;
- 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
- {
- push_parsing_error("opening '[' expected",translation_data);
- return NULL;
- }
- }else
- {
- push_parsing_error("expected a name for the machine",translation_data);
- return NULL;
- }
- }else
- {
- push_parsing_error("'machine' expected",translation_data);
- return NULL;
- }
-}
-/*
- * machine-inner : 'states' '[' states-inner ']' ';'
- * 'events' '[' events-inner ']' ';'
- * 'transitions' '[' transitions-inner ']' ';'
- * 'starting' start-on-inner ';'
- */
-struct AST_Machine* parse_machine_inner(struct token *machine_id,struct Translation_Data *translation_data)
-{
- struct AST_States *states=NULL;
- struct AST_Events *events=NULL;
- struct AST_Transitions *transitions=NULL;
- struct AST_State *starting_state=NULL;
- unsigned char i;
- for(i=0;i<4;++i)
- switch(get_kw(translation_data))
- {
- case KW_STATES:
- if(states)
- {
- push_parsing_error("defining two sets of states",translation_data);
- goto error_cleanup;
- }else
- {
- chomp(translation_data);
- if(get_and_check(translation_data,KW_OPEN_SQUARE))
- {
- states=parse_states_inner(translation_data);
- if(!get_and_check(translation_data,KW_CLOSE_SQUARE)
- || !get_and_check(translation_data,KW_SEMI_COLUMN))
- {
- push_parsing_error("expected ']' and ';' at "
- "end of states definition",translation_data);
- goto error_cleanup;
- }
-
- }else
- {
- push_parsing_error("expected '[' ",translation_data);
- goto error_cleanup;
- }
- }
- break;
- case KW_TRANSITIONS:
- if(states==NULL && events==NULL)
- {
- push_parsing_error("defining transitions before states and events",translation_data);
- goto error_cleanup;
- }else if(transitions)
- {
- push_parsing_error("defining two sets of transitions",translation_data);
- goto error_cleanup;
- }else
- {
- chomp(translation_data);
- if(get_and_check(translation_data,KW_OPEN_SQUARE))
- {
- transitions=parse_transitions_inner(translation_data,states,events);
- if(!get_and_check(translation_data,KW_CLOSE_SQUARE)
- || !get_and_check(translation_data,KW_SEMI_COLUMN))
- {
- push_parsing_error("expected ']' and ';' at "
- "end of transitions definition",translation_data);
- goto error_cleanup;
- }
- }else
- {
- push_parsing_error("expected '[' ",translation_data);
- goto error_cleanup;
- }
- }
- break;
- case KW_EVENTS:
- if(events)
- {
- push_parsing_error("defining two sets of transitions",translation_data);
- goto error_cleanup;
- }else
- {
- chomp(translation_data);
- if(get_and_check(translation_data,KW_OPEN_SQUARE))
- {
- events=parse_events_inner(translation_data);
- if(!get_and_check(translation_data,KW_CLOSE_SQUARE)
- || !get_and_check(translation_data,KW_SEMI_COLUMN))
- {
- push_parsing_error("expected ']' and ';' at "
- "end of events definition",translation_data);
- goto error_cleanup;
- }
- }else
- {
- push_parsing_error("expected '[' ",translation_data);
- goto error_cleanup;
- }
- }
- break;
- case KW_STARTING:
- chomp(translation_data);
- if(!starting_state)
- {
- if(states)
- {
- starting_state=parse_start_on(translation_data,states);
- if(!get_and_check(translation_data,KW_SEMI_COLUMN))
- {
- push_parsing_error("expected ';' at end "
- "of starting state declaration",translation_data);
- goto error_cleanup;
- }
- }else
- {
- push_parsing_error("states need to be defined"
- " before defining a starting one",translation_data);
- goto error_cleanup;
- }
- }else
- {
- push_parsing_error("starting state is defined",translation_data);
- goto error_cleanup;
- }
- break;
- default:
- push_parsing_error("expected states transitions or events",translation_data);
- goto error_cleanup;
-
- }
-
- return get_ast_machine(machine_id,states,events,transitions,starting_state);
-
-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;
-}
-/*
- * states-inner: state (, state)*
- *
- */
-struct AST_States* parse_states_inner(struct Translation_Data *translation_data)
-{
- struct Queue *ids;
- struct AST_State *hold_state;
-
- ids=parse_list((struct AST*(*)(struct Translation_Data*))parse_state,translation_data,KW_COMMA);
- if(ids->size==0)
- {
- push_parsing_error("there needs to be atleast one state",translation_data);
- free(ids);
- return NULL;
- }else
- {
-
- return get_ast_states(ids);
- }
-}
-/*
- * state : id
- *
- */
-struct AST_State* parse_state(struct Translation_Data *translation_data)
-{
- if(get_kw(translation_data)==KW_ID)
- return get_ast_state(Queue_Pop(translation_data->tokens));
- else
- return NULL;
-}
-/*
- * events-inner: id (, id)*
- *
- */
-struct AST_Events* parse_events_inner(struct Translation_Data *translation_data)
-{
- struct Queue *ids;
- ids=parse_list((struct AST*(*)(struct Translation_Data*))parse_event,translation_data,KW_COMMA);
- if(ids->size==0)
- {
- push_parsing_error("there needs to be atleast one event",translation_data);
- return NULL;
- }else
- {
- return get_ast_events(ids);
- }
-}
-struct AST_Event* parse_event(struct Translation_Data *translation_data)
-{
- if(get_kw(translation_data)==KW_ID)
- return get_ast_event(Queue_Pop(translation_data->tokens));
- else
- return NULL;
-}
-/*
- * transitions-inner: ( transition ;)*
- */
-struct AST_Transitions* parse_transitions_inner(struct Translation_Data *translation_data,struct AST_States *states,struct AST_Events *events)
-{
- struct Queue *transitions;
- struct AST_Transition *hold_transition;
-
- transitions=malloc(sizeof(struct Queue));
- Queue_Init(transitions);
-
- while((hold_transition=parse_transition(translation_data,states,events))!=NULL)
- {
- Queue_Push(transitions,hold_transition);
- if(!get_and_check(translation_data,KW_SEMI_COLUMN))
- break;
- }
-
- if(transitions->size==0)
- {
- push_parsing_error("there are no transitions",translation_data);
- return NULL;
- }else
- {
- return get_ast_transitions(transitions);
- }
-}
-/*
- * transition: 'from' state_id 'to' state_id 'on' 'event' event_id [ 'execute' pipeline ]
- *
- */
-struct AST_Transition* parse_transition(struct Translation_Data *translation_data,struct AST_States *states,struct AST_Events *events)
-{
- struct AST_Transition *ret;
- struct AST_State *hold_from;
- struct AST_State *hold_to;
- struct AST_Event *hold_event;
- struct AST_Pipeline *hold_pipeline=NULL;
- struct token *hold_token;
-
- if(get_and_check(translation_data,KW_FROM))
- {
- if(get_kw(translation_data)==KW_ID)
- {
- hold_token=Queue_Pop(translation_data->tokens);
- hold_from=Map_Check(states->states_map,hold_token->data,hold_token->size);
- delete_token(hold_token);
- if(hold_from!=NULL)
- {
- if(get_and_check(translation_data,KW_TO))
- {
- if(get_kw(translation_data)==KW_ID)
- {
- hold_token=Queue_Pop(translation_data->tokens);
- hold_to=Map_Check(states->states_map,hold_token->data,hold_token->size);
- delete_token(hold_token);
- if(hold_to!=NULL)
- {
- if(get_and_check(translation_data,KW_ON) && get_and_check(translation_data,KW_EVENT) )
- {
- if(get_kw(translation_data)==KW_ID)
- {
- hold_token=Queue_Pop(translation_data->tokens);
- hold_event=Map_Check(events->events_map,hold_token->data,hold_token->size);
- delete_token(hold_token);
- if(hold_event!=NULL)
- {
- if(get_and_check(translation_data,KW_EXECUTE))
- if((hold_pipeline=parse_pipeline(translation_data))==NULL)
- { push_parsing_error("after execute",translation_data); return NULL; }
- /*GOAL*/
- return get_ast_transition(hold_from,hold_to,hold_event,hold_pipeline);
- }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; }
- }else { push_parsing_error("using undefined to state in transition",translation_data); }
- }else { push_parsing_error("expected id in transition expression",translation_data); return NULL; }
- }else { push_parsing_error("expected 'to'",translation_data); return NULL; }
- }else { push_parsing_error("using undefined from state in transition",translation_data); return NULL; }
- }else { push_parsing_error("expected id in transition expression",translation_data); return NULL; }
- }else { return NULL; }
-}
-/*
- * pipeline: [ command ( | command )* ]
- *
- */
-struct AST_Pipeline* parse_pipeline(struct Translation_Data *translation_data)
-{
- struct Queue *pipeline;
- pipeline=parse_list((struct AST*(*)(struct Translation_Data*))parse_command,translation_data,KW_PIPE);
- if(pipeline->size==0)
- {
- free(pipeline);
- push_parsing_error("pipeline is empty",translation_data);
- return NULL;
- }else
- {
- return get_ast_pipeline(pipeline);
- }
-}
-/*
- * command: id [ string ]
- *
- */
-struct AST_Command* parse_command(struct Translation_Data *translation_data)
-{
- struct token *id;
- struct token *string=NULL;
- 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);
- }else
- {
- push_parsing_error("expected command id",translation_data);
- return NULL;
- }
-}
-/*
- * starting-on-inner: 'on' id ;
- */
-struct AST_State* parse_start_on(struct Translation_Data *translation_data,struct AST_States *states)
-{
- struct token *hold_id;
- struct AST_State *hold_state;
-
- if(get_and_check(translation_data,KW_ON))
- {
- if(get_kw(translation_data)==KW_ID)
- {
- hold_id=Queue_Pop(translation_data->tokens);
- hold_state=Map_Check(states->states_map,hold_id->data,hold_id->size);
- free(hold_id);
- if(hold_state)
- {
-
- return hold_state;
-
- }else { push_parsing_error("starting state is not defined",translation_data); return NULL; }
- }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 *ret;
-
- ret=malloc(sizeof(struct AST_State));
- ret->type=AST_TYPE_STATE;
- ret->id=id;
-
- return ret;
-}
-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;
-
- return ret;
-}
-struct AST_States* get_ast_states(struct Queue *states)
-{
- struct AST_States *ret;
- struct AST_State *hold_state;
-
- /*perhaps no states error should be handled here*/
- assert(states && states->size>0);
-
- ret=malloc(sizeof(struct AST_States)+sizeof(struct AST_Event *[states->size]));
- ret->type=AST_TYPE_STATES;
- ret->number_of_states=states->size;
- ret->states_map=malloc(sizeof(struct Map));
-
- Map_Init(ret->states_map);
-
- while(states->size>0)
- {
- hold_state=Queue_Pop(states);
- Map_Push(ret->states_map,hold_state->id->data,hold_state->id->size,hold_state);
- ret->states[states->size]=hold_state;
- }
-
- assert(states->size==0);
- free(states);
-
- return ret;
-}
-struct AST_Events* get_ast_events(struct Queue *events)
-{
- struct AST_Events *ret;
- struct AST_Event *hold_event;
-
- /*perhaps no events error should be handled here*/
- assert(events && events->size>0);
-
- ret=malloc(sizeof(struct AST_Events)+sizeof(struct AST_Event *[events->size]));
- ret->type=AST_TYPE_EVENTS;
- ret->number_of_events=events->size;
- ret->events_map=malloc(sizeof(struct Map));
-
- Map_Init(ret->events_map);
-
- while(events->size>0)
- {
- hold_event=Queue_Pop(events);
- Map_Push(ret->events_map,hold_event->id->data,hold_event->id->size,hold_event);
- ret->events[events->size]=hold_event;
- }
-
- assert(events->size==0);
- free(events);
-
- return ret;
-}
-struct AST_Transition* get_ast_transition(struct AST_State *from,struct AST_State *to,struct AST_Event *event,struct AST_Pipeline *pipeline)
-{
- struct AST_Transition *ret;
- ret=malloc(sizeof(struct AST_Transition));
- ret->type=AST_TYPE_TRANSITION;
- ret->from=from;
- ret->to=to;
- ret->event=event;
- ret->pipeline=pipeline;
-
- return ret;
-}
-struct AST_Command* get_ast_command(struct token *function_name,struct token *argument)
-{
- struct AST_Command *ret;
- ret=malloc(sizeof(struct AST_Command));
- ret->type=AST_TYPE_COMMAND;
- ret->function_name=function_name;
- ret->argument=argument;
-
- return ret;
-}
-struct AST_Pipeline* get_ast_pipeline(struct Queue *pipeline)
-{
- struct AST_Pipeline *ret;
-
- ret=malloc(sizeof(struct AST_Pipeline)+sizeof(struct AST_Command *[pipeline->size]));
- ret->type=AST_TYPE_PIPELINE;
- ret->size=pipeline->size;
- pointer_array_fill((void**)ret->pipeline,pipeline);
-
- assert(pipeline->size==0);
- free(pipeline);
-
- return ret;
-}
-struct AST_Machine* get_ast_machine(struct token *id,struct AST_States *states,struct AST_Events *events,struct AST_Transitions *transitions,struct AST_State *starting_state)
-{
- struct AST_Machine *ret;
-
- ret=malloc(sizeof(struct AST_Machine));
- ret->type=AST_TYPE_MACHINE;
- ret->id=id;
- ret->states=states;
- ret->events=events;
- ret->transitions=transitions;
-
- return ret;
-}
-struct AST_Transitions* get_ast_transitions(struct Queue *transitions)
-{
- struct AST_Transitions *ret;
- ret=malloc(sizeof(struct AST_Transitions)+sizeof(struct AST_Transition *[transitions->size]));
- ret->type=AST_TYPE_TRANSITIONS;
- ret->size=transitions->size;
-
- pointer_array_fill((void**)ret->transitions,transitions);
-
- assert(transitions->size==0);
- free(transitions);
-
- return ret;
-}
-void delete_ast(struct AST* ast)
-{
- switch(ast->type)
- {
- case AST_TYPE_MACHINE:
- delete_ast_machine((struct AST_Machine*)ast);
- break;
- case AST_TYPE_STATE:
- delete_ast_state((struct AST_State*)ast);
- break;
- case AST_TYPE_STATES:
- delete_ast_states((struct AST_States*)ast);
- break;
- case AST_TYPE_EVENT:
- delete_ast_event((struct AST_Event*)ast);
- break;
- case AST_TYPE_EVENTS:
- delete_ast_events((struct AST_Events*)ast);
- break;
- case AST_TYPE_TRANSITION:
- delete_ast_transition((struct AST_Transition*)ast);
- break;
- case AST_TYPE_TRANSITIONS:
- delete_ast_transitions((struct AST_Transitions*)ast);
- break;
- case AST_TYPE_COMMAND:
- delete_ast_command((struct AST_Command*)ast);
- break;
- case AST_TYPE_PIPELINE:
- delete_ast_pipeline((struct AST_Pipeline*)ast);
- break;
- }
-}
-void delete_ast_event(struct AST_Event* ast)
-{
- if(ast==NULL)return;
- delete_token(ast->id);
- free(ast);
-}
-void delete_ast_states(struct AST_States* ast)
-{
- size_t i;
- if(ast==NULL)return;
- for(i=0;i<ast->number_of_states;++i)
- delete_ast_state(ast->states[i]);
- free(ast);
-}
-void delete_ast_events(struct AST_Events* ast)
-{
- size_t i;
- if(ast==NULL)return;
- for(i=0;i<ast->number_of_events;++i)
- delete_ast_event(ast->events[i]);
- free(ast);
-}
-void delete_ast_transition(struct AST_Transition* ast)
-{
- if(ast==NULL)return;
- if(ast->pipeline!=NULL)
- delete_ast_pipeline(ast->pipeline);
- free(ast);
-}
-void delete_ast_command(struct AST_Command* ast)
-{
- if(ast==NULL)return;
- delete_token(ast->function_name);
- if(ast->argument!=NULL)
- delete_token(ast->argument);
- free(ast);
-}
-void delete_ast_pipeline(struct AST_Pipeline* ast)
-{
- size_t i;
- if(ast==NULL)return;
- for(i=0;i<ast->size;++i)
- delete_ast_command(ast->pipeline[i]);
- free(ast);
-}
-void delete_ast_machine(struct AST_Machine* ast)
-{
- if(ast==NULL)return;
- if(ast->id!=NULL)
- delete_token(ast->id);
- if(ast->states!=NULL)
- delete_ast_states(ast->states);
- if(ast->events!=NULL)
- delete_ast_events(ast->events);
- if(ast->transitions!=NULL)
- delete_ast_transitions(ast->transitions);
-}
-void delete_ast_transitions(struct AST_Transitions* ast)
-{
- size_t i;
- if(ast==NULL)return;
- for(i=0;i<ast->size;++i)
- delete_ast_transition(ast->transitions[i]);
- free(ast);
-}
-void delete_ast_state(struct AST_State* ast)
-{
- if(ast==NULL)return;
- if(ast->id!=NULL)
- delete_token(ast->id);
- free(ast);
-}
-void pointer_array_fill(void **array,struct Queue *q)
-{
- size_t i;
- for(i=0;q->size>0;++i)
- array[i]=Queue_Pop(q);
-}
-
-struct Queue* parse_list(struct AST *(*parser)(struct Translation_Data*),struct Translation_Data *translation_data,enum Keyword delim)
-{
- struct Queue *q;
- struct AST* hold_ast;
-
- q=malloc(sizeof(struct Queue));
- Queue_Init(q);
- while(hold_ast=parser(translation_data))
- {
- Queue_Push(q,hold_ast);
- if(!get_and_check(translation_data,delim))
- break;
- }
- return q;
-}
-
-#endif