From b845e4754be86d2216733d9bea75cb301f38739d Mon Sep 17 00:00:00 2001 From: Galin Simeonov Date: Fri, 4 Jun 2021 13:04:36 +0300 Subject: added expressions and the if statement --- src/backend/backend.c | 30 ++++++------ src/backend/targets/C/ast_to_c.c | 2 +- src/backend/targets/C/ast_to_c.h | 2 +- src/backend/targets/print/print.c | 97 ++++++++++++++++++++++++++++++++++++-- src/backend/targets/print/print.h | 4 ++ src/frontend/lexer.c | 4 +- src/frontend/parser.c | 36 +++++++++----- src/frontend/parser.h | 2 + src/main.c | 20 ++++---- src/program/program.c | 2 +- src/program/program.h | 2 +- tests/.test5.swp | Bin 0 -> 12288 bytes tests/test4 | 2 +- tests/test5 | 11 +++++ 14 files changed, 168 insertions(+), 46 deletions(-) create mode 100644 tests/.test5.swp create mode 100644 tests/test5 diff --git a/src/backend/backend.c b/src/backend/backend.c index 6646e6c..512d247 100644 --- a/src/backend/backend.c +++ b/src/backend/backend.c @@ -43,7 +43,7 @@ struct State_And_Transitions** extract_transition_table(struct AST_States *state _Bool expression_is_binary(struct AST* expression) { - return (expression->type==AST_TYPE_OP_OR || expression->type==AST_TYPE_OP_AND); + return (expression->type==AST_TYPE_OP_OR || expression->type==AST_TYPE_OP_AND || expression->type==AST_TYPE_OP_SELECTOR); } _Bool expression_is_unary(struct AST* expression) { @@ -93,25 +93,23 @@ void anotate_unchecked_states(struct AST_Translation_Unit *unit,struct Translati size_t i; for(i=0;inumber_of_machines;++i) { - anotate_machine(unit->machines[i],unit); + anotate_machine(unit->machines[i],unit,translation_data); } - if(has_new_errors( - } void anotate_machine(struct AST_Machine *machine,struct AST_Translation_Unit *unit,struct Translation_Data *translation_data) { size_t i; for(i=0;itransitions->size;++i) { - machine->transitions->transitions[i]->from=anotate_expression(machine->transitions->transitions[i]->from,machine,unit); + machine->transitions->transitions[i]->from=anotate_expression(machine->transitions->transitions[i]->from,unit,machine,translation_data); } if(has_new_errors(translation_data)) { - push_error_with_token("in machine",translation_data,machine->id); + push_error_with_token("in machine",machine->id,translation_data); delete_ast_machine(machine); } } -struct AST* anotate_expression(struct AST *expression,struct AST_Translation_Unit *unit,struct AST_Machine *current_machine,struct Translation_Data *translation_data); +struct AST* anotate_expression(struct AST *expression,struct AST_Translation_Unit *unit,struct AST_Machine *current_machine,struct Translation_Data *translation_data) { struct AST_Machine *hold_machine; struct AST *hold_left; @@ -119,8 +117,8 @@ struct AST* anotate_expression(struct AST *expression,struct AST_Translation_Uni if(expression_is_binary(expression)) { - left=((struct AST_Binary_Expression*)expression)->left; - right=((struct AST_Binary_Expression*)expression)->right; + hold_left=((struct AST_Binary_Expression*)expression)->left; + hold_right=((struct AST_Binary_Expression*)expression)->right; if(expression->type==AST_TYPE_OP_SELECTOR) { @@ -132,20 +130,24 @@ struct AST* anotate_expression(struct AST *expression,struct AST_Translation_Uni return NULL; }else { - return ast_check_state(hold_right,hold_machine->states,translation_data); + hold_left=(struct AST*)ast_check_state((struct AST_Unchecked_State*)hold_right,hold_machine->states,translation_data); + ((struct AST_State*)hold_left)->parent=hold_machine; + return hold_left; } }else { - AS_BIN_EXPR_PTR(expression)->right=anotate_expression(AS_BIN_EXPR_PTR(expression)->right,machine,unit); - AS_BIN_EXPR_PTR(expression)->left=anotate_expression(AS_BIN_EXPR_PTR(expression)->left,machine,unit); + AS_BIN_EXPR_PTR(expression)->right=anotate_expression(AS_BIN_EXPR_PTR(expression)->right,unit,current_machine,translation_data); + AS_BIN_EXPR_PTR(expression)->left=anotate_expression(AS_BIN_EXPR_PTR(expression)->left,unit,current_machine,translation_data); return expression; } }else if(expression_is_unary(expression)) { - AS_UN_EXPR_PTR(expression)->operand=anotate_expression(AS_UN_EXPR_PTR(expression)->operand,machine,unit); + AS_UN_EXPR_PTR(expression)->operand=anotate_expression(AS_UN_EXPR_PTR(expression)->operand,unit,current_machine,translation_data); }else if(expression->type==AST_TYPE_UNFINISHED_STATE) { - return ast_check_state(AS_UNCK_EXPR_PTR(expression),machine->states,translation_data); + hold_left=(struct AST*)ast_check_state((struct AST_Unchecked_State*)expression,current_machine->states,translation_data); + ((struct AST_State*)hold_left)->parent=current_machine; + return hold_left; } } #endif diff --git a/src/backend/targets/C/ast_to_c.c b/src/backend/targets/C/ast_to_c.c index 79d6017..3ce923d 100644 --- a/src/backend/targets/C/ast_to_c.c +++ b/src/backend/targets/C/ast_to_c.c @@ -3,7 +3,7 @@ #include #include -void ast_to_c(char *output_name,struct AST *tree) +void ast_to_c(char *output_name,struct AST_Translation_Unit *tree) { size_t output_name_length; char *hold_name; diff --git a/src/backend/targets/C/ast_to_c.h b/src/backend/targets/C/ast_to_c.h index 6e4006f..fb3e729 100644 --- a/src/backend/targets/C/ast_to_c.h +++ b/src/backend/targets/C/ast_to_c.h @@ -9,7 +9,7 @@ struct State_And_Transitions; -void ast_to_c(char *output_name,struct AST *tree); +void ast_to_c(char *output_name,struct AST_Translation_Unit *tree); void ast_translation_unit_to_c_print_header_part(FILE *out,char *base_name,struct AST_Translation_Unit *translation_unit); void ast_translation_unit_to_c_print_body_part(FILE *out,char *base_name,struct AST_Translation_Unit *translation_unit); diff --git a/src/backend/targets/print/print.c b/src/backend/targets/print/print.c index 8eae3dd..7649b91 100644 --- a/src/backend/targets/print/print.c +++ b/src/backend/targets/print/print.c @@ -36,6 +36,12 @@ void print_keyword_enum(enum Keyword code) case KW_CLOSE_SQUARE: printf("KW_CLOSE_SQUARE"); break; + case KW_OPEN_NORMAL: + printf("KW_OPEN_NORMAL"); + break; + case KW_CLOSE_NORMAL: + printf("KW_CLOSE_NORMAL"); + break; case KW_PIPE: printf("KW_PIPE"); break; @@ -54,15 +60,27 @@ void print_keyword_enum(enum Keyword code) case KW_EVENT: printf("KW_EVENT"); break; - case KW_TRANSITIONS: - printf("KW__TRANSITIONS"); - break; case KW_EXECUTE: printf("KW_EXECUTE"); break; + case KW_TRANSITIONS: + printf("KW_TRANSITIONS"); + break; case KW_COMMA: printf("KW_COMMA"); break; + case KW_DOT: + printf("KW_DOT"); + break; + case KW_AND: + printf("KW_AND"); + break; + case KW_OR: + printf("KW_OR"); + break; + case KW_NOT: + printf("KW_NOT"); + break; default: printf("LEXERROR"); } @@ -95,6 +113,9 @@ void print_ast_enum(enum AST_Type type) { switch(type) { + case AST_TYPE_TRANSLATION_UNIT: + printf("AST_TYPE_TRANSLATION_UNIT"); + break; case AST_TYPE_MACHINE: printf("AST_TYPE_MACHINE"); break; @@ -122,6 +143,21 @@ void print_ast_enum(enum AST_Type type) case AST_TYPE_PIPELINE: printf("AST_TYPE_PIPELINE"); break; + case AST_TYPE_OP_AND: + printf("AST_TYPE_OP_AND"); + break; + case AST_TYPE_OP_OR: + printf("AST_TYPE_OP_OR"); + break; + case AST_TYPE_OP_NOT: + printf("AST_TYPE_OP_NOT"); + break; + case AST_TYPE_OP_SELECTOR: + printf("AST_TYPE_OP_SELECTOR"); + break; + case AST_TYPE_UNFINISHED_STATE: + printf("AST_TYPE_UNFINISHED_STATE"); + break; default: printf("AST_NOP"); } @@ -160,6 +196,20 @@ void print_ast(struct AST *tree) case AST_TYPE_PIPELINE: print_ast_pipeline((struct AST_Pipeline*)tree); break; + case AST_TYPE_TRANSLATION_UNIT: + print_ast_translation_unit((struct AST_Translation_Unit*)tree); + break; + case AST_TYPE_OP_AND: + case AST_TYPE_OP_OR: + case AST_TYPE_OP_SELECTOR: + print_ast_binary_expression((struct AST_Binary_Expression*)tree); + break; + case AST_TYPE_OP_NOT: + print_ast_unary_expression((struct AST_Unary_Expression*)tree); + break; + case AST_TYPE_UNFINISHED_STATE: + print_ast_unchecked_state((struct AST_Unchecked_State*)tree); + break; default: printf("noast"); } @@ -212,7 +262,7 @@ void print_ast_transition(struct AST_Transition* tree) assert(tree); printf("TRANSITION [\nFROM"); - print_ast_state(tree->from); + print_ast(tree->from); printf(" TO "); print_ast_state(tree->to); printf(" COMMAND {"); @@ -292,4 +342,43 @@ void print_errors(struct Translation_Data *translation_data) print_error(it->data); } } +void print_ast_translation_unit(struct AST_Translation_Unit *tree) +{ + size_t i; + printf("TRANSLATION UNIT\n[\n"); + for(i=0;inumber_of_machines;++i) + print_ast_machine(tree->machines[i]); + printf("\n] TRANSLATION UNIT END \n"); +} +void print_ast_binary_expression(struct AST_Binary_Expression *tree) +{ + printf(" ("); + print_ast(tree->left); + switch(tree->type) + { + case AST_TYPE_OP_AND: + printf("&&"); + break; + case AST_TYPE_OP_OR: + printf("||"); + break; + case AST_TYPE_OP_SELECTOR: + printf("."); + break; + default: + printf("?!!?!?!?"); + } + print_ast(tree->right); + printf(")"); +} +void print_ast_unary_expression(struct AST_Unary_Expression *tree) +{ + printf("(!"); + print_ast(tree->operand); + printf(")"); +} +void print_ast_unchecked_state(struct AST_Unchecked_State *tree) +{ + print_token(tree->name); +} #endif diff --git a/src/backend/targets/print/print.h b/src/backend/targets/print/print.h index 54d47ce..d318792 100644 --- a/src/backend/targets/print/print.h +++ b/src/backend/targets/print/print.h @@ -21,6 +21,10 @@ 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_ast_translation_unit(struct AST_Translation_Unit *tree); +void print_ast_binary_expression(struct AST_Binary_Expression *tree); +void print_ast_unary_expression(struct AST_Unary_Expression *tree); +void print_ast_unchecked_state(struct AST_Unchecked_State *tree); void print_error(struct Error *error); void print_errors(struct Translation_Data *translation_data); diff --git a/src/frontend/lexer.c b/src/frontend/lexer.c index de8ff95..668d7cd 100644 --- a/src/frontend/lexer.c +++ b/src/frontend/lexer.c @@ -49,10 +49,10 @@ struct token* lex_step(struct Source *src,struct Translation_Data *translation_d return get_token(src->src+src->where_in_src-sizeof("]")+1,sizeof("]")-1,KW_CLOSE_SQUARE,src->current_row,src->current_column); if(check_and_move_if_on_word(";",sizeof(";")-1,src,0)) return get_token(src->src+src->where_in_src-sizeof(";")+1,sizeof(";")-1,KW_SEMI_COLUMN,src->current_row,src->current_column); - if(check_and_move_if_on_word("|",sizeof("|")-1,src,0)) - return get_token(src->src+src->where_in_src-sizeof("|")+1,sizeof("|")-1,KW_PIPE,src->current_row,src->current_column); if(check_and_move_if_on_word("||",sizeof("||")-1,src,0)) return get_token(src->src+src->where_in_src-sizeof("||")+1,sizeof("||")-1,KW_OR,src->current_row,src->current_column); + if(check_and_move_if_on_word("|",sizeof("|")-1,src,0)) + return get_token(src->src+src->where_in_src-sizeof("|")+1,sizeof("|")-1,KW_PIPE,src->current_row,src->current_column); if(check_and_move_if_on_word("&&",sizeof("&&")-1,src,0)) return get_token(src->src+src->where_in_src-sizeof("&&")+1,sizeof("&&")-1,KW_AND,src->current_row,src->current_column); if(check_and_move_if_on_word("!",sizeof("!")-1,src,0)) diff --git a/src/frontend/parser.c b/src/frontend/parser.c index a260622..fa692f5 100644 --- a/src/frontend/parser.c +++ b/src/frontend/parser.c @@ -25,7 +25,6 @@ struct AST_Translation_Unit* parse_translation_unit(struct Translation_Data *tra Map_Init(hold_machines_map); translation_data->hold_command_map=hold_command_map; - translation_data->hold_machines_map=hold_machines_map; while(!get_and_check(translation_data,KW_EOF)) { @@ -332,7 +331,7 @@ struct AST_Transitions* parse_transitions_inner(struct Translation_Data *transla 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 *hold_from; struct AST_State *hold_to; struct AST_Event *hold_event; struct AST_Pipeline *hold_pipeline=NULL; @@ -448,9 +447,11 @@ 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->name=id; /*number is assigned in get_ast_states*/ + /*parent machine is determined in anotation stage*/ return ret; } @@ -522,7 +523,7 @@ struct AST_Events* get_ast_events(struct Queue *events) return ret; } -struct AST_Transition* get_ast_transition(struct AST *from,struct AST_State *to,struct AST_Event *event,struct AST_Pipeline *pipeline); +struct AST_Transition* get_ast_transition(struct AST *from,struct AST_State *to,struct AST_Event *event,struct AST_Pipeline *pipeline) { struct AST_Transition *ret; ret=malloc(sizeof(struct AST_Transition)); @@ -617,6 +618,21 @@ void delete_ast(struct AST* ast) case AST_TYPE_PIPELINE: delete_ast_pipeline((struct AST_Pipeline*)ast); break; + case AST_TYPE_TRANSLATION_UNIT: + delete_ast_translation_unit((struct AST_Translation_Unit*)ast); + break; + case AST_TYPE_OP_AND: + case AST_TYPE_OP_OR: + case AST_TYPE_OP_SELECTOR: + delete_ast_binary_expression((struct AST_Binary_Expression*)ast); + break; + case AST_TYPE_OP_NOT: + delete_ast_unary_expression((struct AST_Unary_Expression*)ast); + break; + case AST_TYPE_UNFINISHED_STATE: + delete_ast_unchecked_state((struct AST_Unchecked_State*)ast); + break; + } } void delete_ast_event(struct AST_Event* ast) @@ -660,8 +676,6 @@ void delete_ast_pipeline(struct AST_Pipeline* ast) { size_t i; if(ast==NULL)return; - for(i=0;isize;++i) - delete_ast_command(ast->pipeline[i]); free(ast); } void delete_ast_machine(struct AST_Machine* ast) @@ -773,7 +787,7 @@ struct AST* parse_or_expression(struct Translation_Data *translation_data) delete_ast(hold_left_expression); return NULL; } - return (struct AST*)get_ast_binary_expression(left,right,AST_TYPE_OP_OR); + return (struct AST*)get_ast_binary_expression(hold_left_expression,hold_right_expression,AST_TYPE_OP_OR); }else { return hold_left_expression; @@ -801,7 +815,7 @@ struct AST* parse_and_expression(struct Translation_Data *translation_data) delete_ast(hold_left_expression); return NULL; } - return (struct AST*)get_ast_binary_expression(left,right,AST_TYPE_OP_AND); + return (struct AST*)get_ast_binary_expression(hold_left_expression,hold_right_expression,AST_TYPE_OP_AND); }else { return hold_left_expression; @@ -818,7 +832,7 @@ struct AST* parse_not_expression(struct Translation_Data *translation_data) hold_expression=parse_primary_expression(translation_data); if(hold_expression!=NULL) { - return get_ast_unary_expression(hold_expression,AST_TYPE_OP_NOT); + return (struct AST*)get_ast_unary_expression(hold_expression,AST_TYPE_OP_NOT); }else { push_parsing_error("in '!' expression",translation_data); @@ -857,16 +871,16 @@ struct AST* parse_primary_expression(struct Translation_Data *translation_data) if(get_kw(translation_data)==KW_ID) { hold_id2=get_ast_unchecked_state(Queue_Pop(translation_data->tokens)); - return get_ast_binary_expression(hold_id1,hold_id2,AST_TYPE_OP_SELECTOR); + return (struct AST*)get_ast_binary_expression((struct AST*)hold_id1,(struct AST*)hold_id2,AST_TYPE_OP_SELECTOR); }else { push_parsing_error("expected a state id in selector",translation_data); - delete_ast(hold_id1); + delete_ast((struct AST*)hold_id1); return NULL; } }else { - return hold_id1; + return (struct AST*)hold_id1; } }else { diff --git a/src/frontend/parser.h b/src/frontend/parser.h index 74f2ed8..a9f6b89 100644 --- a/src/frontend/parser.h +++ b/src/frontend/parser.h @@ -32,7 +32,9 @@ struct AST }; struct AST_State { + enum AST_Type type; struct token *name; + struct AST_Machine *parent; size_t number; }; struct AST_Event diff --git a/src/main.c b/src/main.c index fe3a9f4..1ad3ae6 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ int main(int argc,char **argv) struct Source *source; struct Program *program; struct Translation_Data *translation_data; - struct AST* translation_unit; + struct AST_Translation_Unit* translation_unit; options=parse_command_line(argc,argv); if(options->src_name==NULL) @@ -38,23 +38,23 @@ int main(int argc,char **argv) print_tokens(translation_data->tokens); }else if(options->target==OPTION_TARGET_AST || options->target==OPTION_TARGET_C) { - //we check because we will probably add more options - - translation_unit=parse_source(translation_data); + translation_unit=(struct AST_Translation_Unit*)parse_source(translation_data); if(has_new_errors(translation_data)) - { - print_errors(translation_data); - return 1; - } + { print_errors(translation_data); return 1; } + + anotate_unchecked_states(translation_unit,translation_data); + + if(has_new_errors(translation_data)) + { print_errors(translation_data); return 1; } if(options->target==OPTION_TARGET_AST) { - print_ast(translation_unit); + print_ast((struct AST*)translation_unit); }else if(options->target==OPTION_TARGET_C) { ast_to_c(options->output_name,translation_unit); } - delete_ast(translation_unit); + delete_ast((struct AST*)translation_unit); } }else diff --git a/src/program/program.c b/src/program/program.c index 2632c57..51757a2 100644 --- a/src/program/program.c +++ b/src/program/program.c @@ -183,7 +183,7 @@ void touch_errors(struct Translation_Data *translation_data) assert(translation_data->hold_number_of_errors>0); --translation_data->hold_number_of_errors; } -void push_error_with_token(char *error_message,struct Translation_Data *translation_data,struct token *token) +void push_error_with_token(char *error_message,struct token *token,struct Translation_Data *translation_data) { Queue_Push(translation_data->errors,get_error(error_message,token->row,token->column)); } diff --git a/src/program/program.h b/src/program/program.h index 1fa0db6..fea0aef 100644 --- a/src/program/program.h +++ b/src/program/program.h @@ -64,7 +64,7 @@ struct Error* get_error(char *message,size_t row,size_t column); void push_lexing_error(char *error_message,struct Source *src,struct Translation_Data *translation_data); void push_parsing_error(char *error_message,struct Translation_Data *translation_data); -void push_error_with_token(char *error_message,struct Translation_Data *translation_data,struct token *token); +void push_error_with_token(char *error_message,struct token *token,struct Translation_Data *translation_data); char has_new_errors(struct Translation_Data *translation_data); void touch_errors(struct Translation_Data *translation_data); char get_and_check(struct Translation_Data *translation_data,enum Keyword kw); diff --git a/tests/.test5.swp b/tests/.test5.swp new file mode 100644 index 0000000..6e03612 Binary files /dev/null and b/tests/.test5.swp differ diff --git a/tests/test4 b/tests/test4 index 5130059..579e54d 100644 --- a/tests/test4 +++ b/tests/test4 @@ -19,6 +19,6 @@ machine temp_switch starting on A; transitions [ - from ( A && !light_on ) to B on event A execute kek; + from ( !A && !light_on ) to B on event A execute kek; ]; ]; diff --git a/tests/test5 b/tests/test5 new file mode 100644 index 0000000..fc9ff67 --- /dev/null +++ b/tests/test5 @@ -0,0 +1,11 @@ +machine A +[ + states [ A ]; + events [ A ]; + starting on A; + transitions + [ + from A to A on event A given (B.C && !C.D) + execute eke; + ]; +]; -- cgit v1.2.3