F diff --git a/src/backend/backend.c b/src/backend/backend.c --- a/src/backend/backend.c +++ b/src/backend/backend.c_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){size_t i;for(i=0;i<unit->number_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;i<machine->transitions->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;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){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;}}#endifF diff --git a/src/backend/targets/C/ast_to_c.c b/src/backend/targets/C/ast_to_c.c --- a/src/backend/targets/C/ast_to_c.c +++ b/src/backend/targets/C/ast_to_c.c#include <ast_to_c.h>#include <print.h>- 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;F diff --git a/src/backend/targets/C/ast_to_c.h b/src/backend/targets/C/ast_to_c.h --- a/src/backend/targets/C/ast_to_c.h +++ b/src/backend/targets/C/ast_to_c.hstruct 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);F diff --git a/src/backend/targets/print/print.c b/src/backend/targets/print/print.c --- a/src/backend/targets/print/print.c +++ b/src/backend/targets/print/print.ccase 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;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");}{switch(type){+ case AST_TYPE_TRANSLATION_UNIT:+ printf("AST_TYPE_TRANSLATION_UNIT");+ break;case AST_TYPE_MACHINE:printf("AST_TYPE_MACHINE");break;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");}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");}assert(tree);printf("TRANSITION [\nFROM");- print_ast_state(tree->from);+ print_ast(tree->from);printf(" TO ");print_ast_state(tree->to);printf(" COMMAND {");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;i<tree->number_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);+ }#endifF diff --git a/src/backend/targets/print/print.h b/src/backend/targets/print/print.h --- a/src/backend/targets/print/print.h +++ b/src/backend/targets/print/print.hvoid 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);F diff --git a/src/frontend/lexer.c b/src/frontend/lexer.c --- a/src/frontend/lexer.c +++ b/src/frontend/lexer.creturn 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))F diff --git a/src/frontend/parser.c b/src/frontend/parser.c --- a/src/frontend/parser.c +++ b/src/frontend/parser.cMap_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)){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;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;}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));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){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)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;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;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);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{F diff --git a/src/frontend/parser.h b/src/frontend/parser.h --- a/src/frontend/parser.h +++ b/src/frontend/parser.h};struct AST_State{+ enum AST_Type type;struct token *name;+ struct AST_Machine *parent;size_t number;};struct AST_EventF diff --git a/src/main.c b/src/main.c --- a/src/main.c +++ b/src/main.cstruct 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)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);}}elseF diff --git a/src/program/program.c b/src/program/program.c --- a/src/program/program.c +++ b/src/program/program.cassert(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));}F diff --git a/src/program/program.h b/src/program/program.h --- a/src/program/program.h +++ b/src/program/program.hvoid 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);F diff --git a/tests/.test5.swp b/tests/.test5.swp new file mode 100644B Binary files /dev/null and b/tests/.test5.swp differF diff --git a/tests/test4 b/tests/test4 --- a/tests/test4 +++ b/tests/test4starting 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;];];F diff --git a/tests/test5 b/tests/test5 new file mode 100644 --- /dev/null +++ b/tests/test5+ machine A+ [+ states [ A ];+ events [ A ];+ starting on A;+ transitions+ [+ from A to A on event A given (B.C && !C.D)+ execute eke;+ ];+ ];