From 85b23fbee717f047af5a89eac6f4dba8e7812524 Mon Sep 17 00:00:00 2001 From: Galin Simeonov Date: Tue, 1 Jun 2021 18:21:02 +0300 Subject: restructuring --- src/backend/backend.c | 37 +++++ src/backend/backend.h | 18 +++ src/backend/print.c | 294 ------------------------------------- src/backend/print.h | 27 ---- src/backend/targets/C/ast_to_c.c | 155 ++++++++++++++++++++ src/backend/targets/C/ast_to_c.h | 29 ++++ src/backend/targets/print/print.c | 295 ++++++++++++++++++++++++++++++++++++++ src/backend/targets/print/print.h | 27 ++++ src/frontend/lexer.h | 2 +- src/frontend/parser.c | 93 ++++++++++-- src/frontend/parser.h | 26 ++-- src/main.c | 18 ++- src/program/program.c | 4 +- src/program/program.h | 2 + 14 files changed, 677 insertions(+), 350 deletions(-) create mode 100644 src/backend/backend.c create mode 100644 src/backend/backend.h delete mode 100644 src/backend/print.c delete mode 100644 src/backend/print.h create mode 100644 src/backend/targets/C/ast_to_c.c create mode 100644 src/backend/targets/C/ast_to_c.h create mode 100644 src/backend/targets/print/print.c create mode 100644 src/backend/targets/print/print.h (limited to 'src') diff --git a/src/backend/backend.c b/src/backend/backend.c new file mode 100644 index 0000000..122e84c --- /dev/null +++ b/src/backend/backend.c @@ -0,0 +1,37 @@ +#ifndef BACKEND_C +#define BACKEND_C BACKEND_C +#include + +/*returns an array of pointers to state_and_transition structs*/ +struct State_And_Transitions** extract_transition_table(struct AST_States *states,struct AST_Transitions *transitions) +{ + struct State_And_Transitions **ret; + struct Queue *qs; + size_t i; + + ret=malloc(sizeof(struct State_And_Transitions)*states->number_of_states); + + /*calloc also initialises the queues + *i-th queue is for transitions starting from the i-th state + * */ + qs=calloc(sizeof(struct Queue),states->number_of_states); + + /*traverse transitions and push them into the queue of their coresponding state*/ + for(i=0;isize;++i) + Queue_Push(qs+transitions->transitions[i]->from->number,transitions->transitions[i]); + + /*condense the queues into the arrays*/ + for(i=0;inumber_of_states;++i) + { + ret[i]=malloc(sizeof(struct State_And_Transitions)+sizeof(struct AST_Transitions *[qs[i].size])); + ret[i]->state=states->states[i]; + ret[i]->number_of_transitions=qs[i].size; + pointer_array_fill((void**)ret[i]->transitions,qs+i); + } + + free(qs); + + return ret; +} + +#endif diff --git a/src/backend/backend.h b/src/backend/backend.h new file mode 100644 index 0000000..1857cd0 --- /dev/null +++ b/src/backend/backend.h @@ -0,0 +1,18 @@ +#ifndef BACKEND_H +#define BACKEND_H BACKEND_H +#include +#include + +/* + * describes a given state and the transitions coming out of it + * I should probbably have done this in the parsing stage + */ +struct State_And_Transitions +{ + struct AST_State *state; + size_t number_of_transitions; + struct AST_Transition *transitions[]; +}; +/*returns an array of state_and_transition structs*/ +struct State_And_Transitions** extract_transition_table(struct AST_States *states,struct AST_Transitions *transitions); +#endif diff --git a/src/backend/print.c b/src/backend/print.c deleted file mode 100644 index 614a6c9..0000000 --- a/src/backend/print.c +++ /dev/null @@ -1,294 +0,0 @@ -#ifndef PRINT_C -#define PRINT_C PRINT_C -#include - -void print_keyword_enum(enum Keyword code) -{ - switch(code) - { - case KW_MACHINE: - printf("KW_MACHINE"); - break; - case KW_FROM: - printf("KW_FROM"); - break; - case KW_TO: - printf("KW_TO"); - break; - case KW_ON: - printf("KW_ON"); - break; - case KW_ID: - printf("KW_ID"); - break; - case KW_STRING: - printf("KW_STRING"); - break; - case KW_NOP: - printf("KW_NOP"); - break; - case KW_EOF: - printf("KW_EOF"); - break; - case KW_OPEN_SQUARE: - printf("KW_OPEN_SQUARE"); - break; - case KW_CLOSE_SQUARE: - printf("KW_CLOSE_SQUARE"); - break; - case KW_PIPE: - printf("KW_PIPE"); - break; - case KW_SEMI_COLUMN: - printf("KW_SEMI_COLUMN"); - break; - case KW_STARTING: - printf("KW_STARTING"); - break; - case KW_STATES: - printf("KW_STATES"); - break; - case KW_EVENTS: - printf("KW_EVENTS"); - break; - case KW_EVENT: - printf("KW_EVENT"); - break; - case KW_TRANSITIONS: - printf("KW__TRANSITIONS"); - break; - case KW_EXECUTE: - printf("KW_EXECUTE"); - break; - case KW_COMMA: - printf("KW_COMMA"); - break; - default: - printf("LEXERROR"); - } -} -void print_token(struct token *token) -{ - size_t i; - assert(token); - - printf("[ "); - print_keyword_enum(token->type); - printf(" "); - for(i=0;isize;++i) - printf("%c",token->data[i]); - printf(" ] "); - -} -void print_tokens(struct Queue *tokens) -{ - struct Queue_Node *it; - assert(tokens); - - for(it=tokens->first;it!=NULL;it=it->prev) - { - print_token( (struct token*)(it->data)); - printf(" "); - } -} -void print_ast_enum(enum AST_Type type) -{ - switch(type) - { - case AST_TYPE_MACHINE: - printf("AST_TYPE_MACHINE"); - break; - case AST_TYPE_STATE: - printf("AST_TYPE_STATE"); - break; - case AST_TYPE_STATES: - printf("AST_TYPE_STATES"); - break; - case AST_TYPE_EVENT: - printf("AST_TYPE_EVENT"); - break; - case AST_TYPE_EVENTS: - printf("AST_TYPE_EVENTS"); - break; - case AST_TYPE_TRANSITION: - printf("AST_TYPE_TRANSITION"); - break; - case AST_TYPE_TRANSITIONS: - printf("AST_TYPE_TRANSITIONS"); - break; - case AST_TYPE_COMMAND: - printf("AST_TYPE_COMMAND"); - break; - case AST_TYPE_PIPELINE: - printf("AST_TYPE_PIPELINE"); - break; - default: - printf("AST_NOP"); - } - -} -void print_ast(struct AST *tree) -{ - assert(tree); - - switch(tree->type) - { - case AST_TYPE_MACHINE: - print_ast_machine((struct AST_Machine*)tree); - break; - case AST_TYPE_STATE: - print_ast_state((struct AST_State*)tree); - break; - case AST_TYPE_STATES: - print_ast_states((struct AST_States*)tree); - break; - case AST_TYPE_EVENT: - print_ast_event((struct AST_Event*)tree); - break; - case AST_TYPE_EVENTS: - print_ast_events((struct AST_Events*)tree); - break; - case AST_TYPE_TRANSITION: - print_ast_transition((struct AST_Transition*)tree); - break; - case AST_TYPE_TRANSITIONS: - print_ast_transitions((struct AST_Transitions*)tree); - break; - case AST_TYPE_COMMAND: - print_ast_command((struct AST_Command*)tree); - break; - case AST_TYPE_PIPELINE: - print_ast_pipeline((struct AST_Pipeline*)tree); - break; - default: - printf("noast"); - } -} -void print_ast_state(struct AST_State* tree) -{ - assert(tree); - - printf("[ STATE: "); - print_ast_enum(tree->type); - printf("]"); -} -void print_ast_event(struct AST_Event* tree) -{ - assert(tree); - - printf("[ EVENT: "); - print_ast_enum(tree->type); - printf("]"); -} -void print_ast_states(struct AST_States* tree) -{ - size_t i; - assert(tree); - - printf("STATES [\n"); - for(i=0;inumber_of_states;++i) - { - print_ast_state(tree->states[i]); - printf(" "); - } - printf("\n ] END STATES \n"); -} -void print_ast_events(struct AST_Events* tree) -{ - size_t i; - assert(tree); - - printf("EVENTS [\n"); - for(i=0;inumber_of_events;++i) - { - print_ast_event(tree->events[i]); - printf(" "); - } - printf("\n ] END EVENTS \n"); -} -void print_ast_transition(struct AST_Transition* tree) -{ - assert(tree); - - printf("TRANSITION [\nFROM"); - print_ast_state(tree->from); - printf(" TO "); - print_ast_state(tree->to); - printf(" COMMAND {"); - if(tree->pipeline==NULL) - { - printf("NULL"); - }else - { - print_ast_pipeline(tree->pipeline); - } - -} -void print_ast_command(struct AST_Command* tree) -{ - assert(tree); - - printf("( command "); - print_token(tree->function_name); - if(tree->argument==NULL) - { - printf(" NOARGUMENTS "); - }else - { - printf(" \""); - print_token(tree->argument); - printf("\" "); - } - printf(")"); -} -void print_ast_pipeline(struct AST_Pipeline* tree) -{ - size_t i; - assert(tree); - printf("PIPELINE <"); - for(i=0;isize;++i) - { - print_ast_command(tree->pipeline[i]); - printf(" | "); - } - printf("> PIPELINE_END"); -} -void print_ast_machine(struct AST_Machine* tree) -{ - assert(tree); - printf("MACHINE "); - print_token(tree->id); - printf(" [\n"); - print_ast_states(tree->states); - print_ast_events(tree->events); - print_ast_transitions(tree->transitions); - printf("] MACHINE_END\n"); -} -void print_ast_transitions(struct AST_Transitions* tree) -{ - size_t i; - assert(tree); - printf("TRANSITIONS [\n"); - for(i=0;isize;++i) - { - print_ast_transition(tree->transitions[i]); - printf("\n"); - } - printf("] TRANSITIONS_END\n"); -} -void print_error(struct Error *error) -{ - assert(error); - printf("Error: %s, line %ld row %ld\n",error->message,error->row,error->column); -} -void print_errors(struct Translation_Data *translation_data) -{ - struct Queue_Node *it; - assert(translation_data); - - for(it=translation_data->errors->first;it!=NULL;it=it->prev) - { - print_error(it->data); - } -} -#endif diff --git a/src/backend/print.h b/src/backend/print.h deleted file mode 100644 index 54d47ce..0000000 --- a/src/backend/print.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef PRINT_H -#define PRINT_H PRINT_H -#include -#include -#include -#include - - -void print_keyword_enum(enum Keyword code); -void print_token(struct token *token); -void print_tokens(struct Queue *tokens); - -void print_ast_enum(enum AST_Type type); -void print_ast(struct AST *tree); -void print_ast_state(struct AST_State* tree); -void print_ast_event(struct AST_Event* tree); -void print_ast_states(struct AST_States* tree); -void print_ast_events(struct AST_Events* tree); -void print_ast_transition(struct AST_Transition* tree); -void print_ast_command(struct AST_Command* tree); -void print_ast_pipeline(struct AST_Pipeline* tree); -void print_ast_machine(struct AST_Machine* tree); -void print_ast_transitions(struct AST_Transitions* tree); - -void print_error(struct Error *error); -void print_errors(struct Translation_Data *translation_data); -#endif diff --git a/src/backend/targets/C/ast_to_c.c b/src/backend/targets/C/ast_to_c.c new file mode 100644 index 0000000..346801c --- /dev/null +++ b/src/backend/targets/C/ast_to_c.c @@ -0,0 +1,155 @@ +#ifndef AST_TO_C_C +#define AST_TO_C_C AST_TO_C_C +#include +#include + +void ast_to_c(FILE *out,struct AST *tree) +{ + assert(tree->type==AST_TYPE_MACHINE); + ast_machine_to_c(out,(struct AST_Machine*)tree); +} +void ast_machine_to_c(FILE *out,struct AST_Machine *machine) +{ + + assert(out!=NULL && machine!=NULL && machine->type==AST_TYPE_MACHINE); + + + ast_machine_to_c_make_header_part(out,machine); + ast_machine_to_c_make_body_part(out,machine); + + +} +void ast_machine_to_c_make_body_part(FILE *out,struct AST_Machine *machine) +{ + size_t i; + struct State_And_Transitions **table; + + table=extract_transition_table(machine->states,machine->transitions); + + for(i=0;istates->number_of_states;++i) + { + ast_state_to_c_signature(out,machine,machine->states->states[i]); + fprintf(out,"\n{\n"); + ast_transitions_of_state_to_c(out,machine,table[i]); + fprintf(out,"\n}\n"); + } +} +void ast_machine_to_c_make_header_part(FILE *out,struct AST_Machine *machine) +{ + fprintf(out,"typedef struct machine_buffer_t \n{" + "\n\tsize_t size;\n\tunsigned char buffer[];\n} machine_buffer_t;\n\n"); + ast_events_to_c(out,machine); + ast_states_to_c(out,machine); +} +void ast_events_to_c(FILE *out,struct AST_Machine *machine) +{ + size_t i; + + assert(out!=NULL && machine!=NULL && machine->type==AST_TYPE_MACHINE); + + fprintf(out,"enum "); + ast_event_name_to_c(out,machine); + fprintf(out,"\n{\n"); + + for(i=0;ievents->number_of_events;++i) + { + fprintf(out,"\t"); + ast_token_to_c(out,machine->id); + fprintf(out,"_EVENT_"); + ast_token_to_c(out,machine->events->events[i]->name); + fprintf(out,",\n"); + } + fprintf(out,"};\n"); +} +void ast_states_to_c(FILE *out,struct AST_Machine *machine) +{ + size_t i; + assert(out!=NULL && machine!=NULL && machine->type==AST_TYPE_MACHINE); + for(i=0;istates->number_of_states;++i) + { + fprintf(out,"extern "); + ast_state_to_c_signature(out,machine,machine->states->states[i]); + fprintf(out,";\n"); + } +} +void ast_transitions_of_state_to_c(FILE *out,struct AST_Machine *machine,struct State_And_Transitions *vector) +{ + size_t i; + ast_state_to_c_signature(out,machine,vector->state); + fprintf(out,"\n{\n\n\tswitch(event)\n\t{\n"); + for(i=0;inumber_of_transitions;++i) + { + fprintf(out,"\t\tcase "); + ast_token_to_c(out,vector->transitions[i]->event->name); + fprintf(out,":\n"); + ast_pipeline_to_c(out,3,vector->transitions[i]->pipeline); + fprintf(out,"\n\t\t\tbreak;\n"); + } + +} +void ast_event_name_to_c(FILE *out,struct AST_Machine *machine) +{ + fprintf(out,"MACHINE_"); + ast_token_to_c(out,machine->id); + fprintf(out,"_EVENTS_ENUM"); +} +void ast_state_to_c_signature(FILE *out,struct AST_Machine *machine,struct AST_State *state) +{ + fprintf(out,"void machine_"); + ast_token_to_c(out,machine->id); + fprintf(out,"_state_"); + ast_token_to_c(out,state->name); + fprintf(out,"(enum "); + ast_event_name_to_c(out,machine); + fprintf(out," event)\n"); +} +void ast_token_to_c(FILE *out,struct token *token) +{ + size_t i; + + assert(out!=NULL && token!=NULL); + + for(i=0;isize;++i) + fprintf(out,"%c",token->data[i]); +} +void ast_pipeline_to_c(FILE *out,size_t indentation,struct AST_Pipeline *pipeline) +{ + size_t i; + + ast_to_c_print_tabs(out,indentation); + fprintf(out,"machine_buffer_t *hold_buffer;\n"); + + for(i=0;isize;++i) + { + ast_to_c_print_tabs(out,indentation); + fprintf(out,"hold_buffer="); + ast_command_to_c(out,pipeline->pipeline[i],"hold_buffer"); + fprintf(out,";\n"); + } + ast_to_c_print_tabs(out,indentation); + fprintf(out,"delete_machine_buffer(hold_buffer);\n"); +} +void ast_command_to_c(FILE *out,struct AST_Command *command,char *hold_buffer) +{ + ast_token_to_c(out,command->function_name); + fprintf(out,"("); + if(command->argument==NULL) + fprintf(out,"NULL"); + else + ast_token_to_c(out,command->argument); + fprintf(out,",%s)",hold_buffer); +} + +void ast_command_to_c_signature(FILE *out,struct AST_Command *command) +{ + fprintf(out,"machine_buffer_t* "); + ast_token_to_c(out,command->function_name); + fprintf(out,"machine_buffer_t *arguments,machine_buffer_t *input)"); +} +void ast_to_c_print_tabs(FILE *out,size_t number_of_tabs) +{ + size_t i; + for(i=0;i +#include +#include +#include + +struct State_And_Transitions; + +void ast_to_c(FILE *out,struct AST *tree); +void ast_machine_to_c(FILE *out,struct AST_Machine *machine); +void ast_machine_to_c_make_header_part(FILE *out,struct AST_Machine *machine); +void ast_machine_to_c_make_body_part(FILE *out,struct AST_Machine *machine); + +void ast_events_to_c(FILE *out,struct AST_Machine *machine); +void ast_states_to_c(FILE *out,struct AST_Machine *machine); + +void ast_pipeline_to_c(FILE *out,size_t indentation,struct AST_Pipeline *pipeline); +void ast_command_to_c(FILE *out,struct AST_Command *command,char *hold_buffer); +void ast_command_to_c_signature(FILE *out,struct AST_Command *command); + +void ast_transitions_of_state_to_c(FILE *out,struct AST_Machine *machine,struct State_And_Transitions *vector); +void ast_token_to_c(FILE *out,struct token *token); +void ast_event_name_to_c(FILE *out,struct AST_Machine *machine); +void ast_state_to_c_signature(FILE *out,struct AST_Machine *machine,struct AST_State *state); +/* :X */ +void ast_to_c_print_tabs(FILE *out,size_t number_of_tabs); + +#endif diff --git a/src/backend/targets/print/print.c b/src/backend/targets/print/print.c new file mode 100644 index 0000000..8eae3dd --- /dev/null +++ b/src/backend/targets/print/print.c @@ -0,0 +1,295 @@ +#ifndef PRINT_C +#define PRINT_C PRINT_C +#include + +void print_keyword_enum(enum Keyword code) +{ + switch(code) + { + case KW_MACHINE: + printf("KW_MACHINE"); + break; + case KW_FROM: + printf("KW_FROM"); + break; + case KW_TO: + printf("KW_TO"); + break; + case KW_ON: + printf("KW_ON"); + break; + case KW_ID: + printf("KW_ID"); + break; + case KW_STRING: + printf("KW_STRING"); + break; + case KW_NOP: + printf("KW_NOP"); + break; + case KW_EOF: + printf("KW_EOF"); + break; + case KW_OPEN_SQUARE: + printf("KW_OPEN_SQUARE"); + break; + case KW_CLOSE_SQUARE: + printf("KW_CLOSE_SQUARE"); + break; + case KW_PIPE: + printf("KW_PIPE"); + break; + case KW_SEMI_COLUMN: + printf("KW_SEMI_COLUMN"); + break; + case KW_STARTING: + printf("KW_STARTING"); + break; + case KW_STATES: + printf("KW_STATES"); + break; + case KW_EVENTS: + printf("KW_EVENTS"); + break; + case KW_EVENT: + printf("KW_EVENT"); + break; + case KW_TRANSITIONS: + printf("KW__TRANSITIONS"); + break; + case KW_EXECUTE: + printf("KW_EXECUTE"); + break; + case KW_COMMA: + printf("KW_COMMA"); + break; + default: + printf("LEXERROR"); + } +} +void print_token(struct token *token) +{ + size_t i; + assert(token); + + printf("[ "); + print_keyword_enum(token->type); + printf(" "); + for(i=0;isize;++i) + printf("%c",token->data[i]); + printf(" ] "); + +} +void print_tokens(struct Queue *tokens) +{ + struct Queue_Node *it; + assert(tokens); + + for(it=tokens->first;it!=NULL;it=it->prev) + { + print_token( (struct token*)(it->data)); + printf(" "); + } +} +void print_ast_enum(enum AST_Type type) +{ + switch(type) + { + case AST_TYPE_MACHINE: + printf("AST_TYPE_MACHINE"); + break; + case AST_TYPE_STATE: + printf("AST_TYPE_STATE"); + break; + case AST_TYPE_STATES: + printf("AST_TYPE_STATES"); + break; + case AST_TYPE_EVENT: + printf("AST_TYPE_EVENT"); + break; + case AST_TYPE_EVENTS: + printf("AST_TYPE_EVENTS"); + break; + case AST_TYPE_TRANSITION: + printf("AST_TYPE_TRANSITION"); + break; + case AST_TYPE_TRANSITIONS: + printf("AST_TYPE_TRANSITIONS"); + break; + case AST_TYPE_COMMAND: + printf("AST_TYPE_COMMAND"); + break; + case AST_TYPE_PIPELINE: + printf("AST_TYPE_PIPELINE"); + break; + default: + printf("AST_NOP"); + } + +} +void print_ast(struct AST *tree) +{ + assert(tree); + + switch(tree->type) + { + case AST_TYPE_MACHINE: + print_ast_machine((struct AST_Machine*)tree); + break; + case AST_TYPE_STATE: + print_ast_state((struct AST_State*)tree); + break; + case AST_TYPE_STATES: + print_ast_states((struct AST_States*)tree); + break; + case AST_TYPE_EVENT: + print_ast_event((struct AST_Event*)tree); + break; + case AST_TYPE_EVENTS: + print_ast_events((struct AST_Events*)tree); + break; + case AST_TYPE_TRANSITION: + print_ast_transition((struct AST_Transition*)tree); + break; + case AST_TYPE_TRANSITIONS: + print_ast_transitions((struct AST_Transitions*)tree); + break; + case AST_TYPE_COMMAND: + print_ast_command((struct AST_Command*)tree); + break; + case AST_TYPE_PIPELINE: + print_ast_pipeline((struct AST_Pipeline*)tree); + break; + default: + printf("noast"); + } +} +void print_ast_state(struct AST_State* tree) +{ + assert(tree); + + printf("[ STATE: "); + print_token(tree->name); + printf(" %ld",tree->number); + printf("]"); +} +void print_ast_event(struct AST_Event* tree) +{ + assert(tree); + + printf("[ EVENT: "); + print_token(tree->name); + printf("]"); +} +void print_ast_states(struct AST_States* tree) +{ + size_t i; + assert(tree); + + printf("STATES [\n"); + for(i=0;inumber_of_states;++i) + { + print_ast_state(tree->states[i]); + printf(" "); + } + printf("\n ] END STATES \n"); +} +void print_ast_events(struct AST_Events* tree) +{ + size_t i; + assert(tree); + + printf("EVENTS [\n"); + for(i=0;inumber_of_events;++i) + { + print_ast_event(tree->events[i]); + printf(" "); + } + printf("\n ] END EVENTS \n"); +} +void print_ast_transition(struct AST_Transition* tree) +{ + assert(tree); + + printf("TRANSITION [\nFROM"); + print_ast_state(tree->from); + printf(" TO "); + print_ast_state(tree->to); + printf(" COMMAND {"); + if(tree->pipeline==NULL) + { + printf("NULL"); + }else + { + print_ast_pipeline(tree->pipeline); + } + +} +void print_ast_command(struct AST_Command* tree) +{ + assert(tree); + + printf("( command "); + print_token(tree->function_name); + if(tree->argument==NULL) + { + printf(" NOARGUMENTS "); + }else + { + printf(" \""); + print_token(tree->argument); + printf("\" "); + } + printf(")"); +} +void print_ast_pipeline(struct AST_Pipeline* tree) +{ + size_t i; + assert(tree); + printf("PIPELINE <"); + for(i=0;isize;++i) + { + print_ast_command(tree->pipeline[i]); + printf(" | "); + } + printf("> PIPELINE_END"); +} +void print_ast_machine(struct AST_Machine* tree) +{ + assert(tree); + printf("MACHINE "); + print_token(tree->id); + printf(" [\n"); + print_ast_states(tree->states); + print_ast_events(tree->events); + print_ast_transitions(tree->transitions); + printf("] MACHINE_END\n"); +} +void print_ast_transitions(struct AST_Transitions* tree) +{ + size_t i; + assert(tree); + printf("TRANSITIONS [\n"); + for(i=0;isize;++i) + { + print_ast_transition(tree->transitions[i]); + printf("\n"); + } + printf("] TRANSITIONS_END\n"); +} +void print_error(struct Error *error) +{ + assert(error); + printf("Error: %s, line %ld row %ld\n",error->message,error->row,error->column); +} +void print_errors(struct Translation_Data *translation_data) +{ + struct Queue_Node *it; + assert(translation_data); + + for(it=translation_data->errors->first;it!=NULL;it=it->prev) + { + print_error(it->data); + } +} +#endif diff --git a/src/backend/targets/print/print.h b/src/backend/targets/print/print.h new file mode 100644 index 0000000..54d47ce --- /dev/null +++ b/src/backend/targets/print/print.h @@ -0,0 +1,27 @@ +#ifndef PRINT_H +#define PRINT_H PRINT_H +#include +#include +#include +#include + + +void print_keyword_enum(enum Keyword code); +void print_token(struct token *token); +void print_tokens(struct Queue *tokens); + +void print_ast_enum(enum AST_Type type); +void print_ast(struct AST *tree); +void print_ast_state(struct AST_State* tree); +void print_ast_event(struct AST_Event* tree); +void print_ast_states(struct AST_States* tree); +void print_ast_events(struct AST_Events* tree); +void print_ast_transition(struct AST_Transition* tree); +void print_ast_command(struct AST_Command* tree); +void print_ast_pipeline(struct AST_Pipeline* tree); +void print_ast_machine(struct AST_Machine* tree); +void print_ast_transitions(struct AST_Transitions* tree); + +void print_error(struct Error *error); +void print_errors(struct Translation_Data *translation_data); +#endif diff --git a/src/frontend/lexer.h b/src/frontend/lexer.h index 320146c..d102540 100644 --- a/src/frontend/lexer.h +++ b/src/frontend/lexer.h @@ -32,8 +32,8 @@ enum Keyword }; struct token { - size_t size; enum Keyword type; + size_t size; char *data; size_t row; size_t column; 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 +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;inumber_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 diff --git a/src/frontend/parser.h b/src/frontend/parser.h index ef82184..eaede84 100644 --- a/src/frontend/parser.h +++ b/src/frontend/parser.h @@ -7,6 +7,7 @@ enum AST_Type { + AST_TYPE_TRANSLATION_UNIT, AST_TYPE_MACHINE, AST_TYPE_STATE, AST_TYPE_STATES, @@ -23,13 +24,12 @@ struct AST }; struct AST_State { - enum AST_Type type; - struct token *id; + struct token *name; + size_t number; }; struct AST_Event { - enum AST_Type type; - struct token *id; + struct token *name; }; struct AST_States { @@ -65,6 +65,12 @@ struct AST_Pipeline size_t size; struct AST_Command *pipeline[]; }; +struct AST_Transitions +{ + enum AST_Type type; + size_t size; + struct AST_Transition *transitions[]; +}; struct AST_Machine { enum AST_Type type; @@ -73,15 +79,17 @@ struct AST_Machine struct AST_Events *events; struct AST_Transitions *transitions; }; -struct AST_Transitions +struct AST_Translation_Unit { enum AST_Type type; - size_t size; - struct AST_Transition *transitions[]; + struct Map *used_commands_map; + size_t number_of_machines; + struct AST_Machine *machines[]; }; -struct AST* parse_unit(struct Translation_Data *translation_data); +struct AST* parse_source(struct Translation_Data *translation_data); +struct AST_Translation_Unit* parse_translation_unit(struct Translation_Data *translation_data); struct AST_Machine* parse_machine(struct Translation_Data *translation_data); struct AST_Machine* parse_machine_inner(struct token *machine_id,struct Translation_Data *translation_data); struct AST_States* parse_states_inner(struct Translation_Data *translation_data); @@ -104,6 +112,7 @@ struct AST_Command* get_ast_command(struct token *function_name,struct token *ar struct AST_Pipeline* get_ast_pipeline(struct Queue *pipeline); 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_Transitions* get_ast_transitions(struct Queue *transitions); +struct AST_Translation_Unit* get_ast_translation_unit(struct Queue *machines,struct Map *command_map); void delete_ast(struct AST* ast); @@ -116,6 +125,7 @@ void delete_ast_command(struct AST_Command* ast); void delete_ast_pipeline(struct AST_Pipeline* ast); void delete_ast_machine(struct AST_Machine* ast); void delete_ast_transitions(struct AST_Transitions* ast); +void delete_ast_translation_unit(struct AST_Translation_Unit *ast); void pointer_array_fill(void **array,struct Queue *q); diff --git a/src/main.c b/src/main.c index 438f282..1001c51 100644 --- a/src/main.c +++ b/src/main.c @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -24,7 +25,7 @@ int main(int argc,char **argv) source=extract_source(strndup(options->src_name,100)); translation_data=get_translation_data(); - if(options->target==OPTION_TARGET_TOKENS || options->target==OPTION_TARGET_AST) + if(options->target==OPTION_TARGET_TOKENS || options->target==OPTION_TARGET_AST || options->target==OPTION_TARGET_C) { lex(translation_data->tokens,source,translation_data); if(translation_data->errors->size>0) @@ -35,18 +36,25 @@ int main(int argc,char **argv) }else if(options->target==OPTION_TARGET_TOKENS) { print_tokens(translation_data->tokens); - }else if(options->target==OPTION_TARGET_AST) //we check because we will probably add more options + }else if(options->target==OPTION_TARGET_AST || options->target==OPTION_TARGET_C) { - translation_unit=parse_unit(translation_data); + //we check because we will probably add more options + + + translation_unit=parse_source(translation_data); if(has_new_errors(translation_data)) { print_errors(translation_data); return 1; - }else + } + if(options->target==OPTION_TARGET_AST) { print_ast(translation_unit); - delete_ast(translation_unit); + }else if(options->target==OPTION_TARGET_C) + { + ast_to_c(stdout,translation_unit); } + delete_ast(translation_unit); } }else diff --git a/src/program/program.c b/src/program/program.c index 5cf8cc3..1e7882d 100644 --- a/src/program/program.c +++ b/src/program/program.c @@ -48,6 +48,8 @@ struct Options* parse_command_line(int argc,char **argv) ret->target=OPTION_TARGET_TOKENS; else if(!strncmp(argv[i],"--print-ast",sizeof("--print-ast"))) ret->target=OPTION_TARGET_AST; + else if(!strncmp(argv[i],"--print-c",sizeof("--print-c"))) + ret->target=OPTION_TARGET_C; else if(!strncmp(argv[i],"-o",sizeof("-o")) || !strncmp(argv[i],"--output",sizeof("--output"))) { if(++itarget==OPTION_DEFAULT) - ret->target=OPTION_TARGET_AST; + ret->target=OPTION_TARGET_C; return ret; } diff --git a/src/program/program.h b/src/program/program.h index d5e45b7..99a02c3 100644 --- a/src/program/program.h +++ b/src/program/program.h @@ -14,6 +14,7 @@ enum Options_Target_Type { OPTION_TARGET_TOKENS, OPTION_TARGET_AST, + OPTION_TARGET_C, OPTION_DEFAULT, }; @@ -47,6 +48,7 @@ struct Translation_Data struct Queue *errors; struct Queue *tokens; size_t hold_number_of_errors; + struct Map *hold_command_map; }; struct Program { -- cgit v1.2.3