MEGATRON



LOG | FILES | OVERVIEW


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;
}
}
#endif
F 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.h
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);
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.c
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;
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);
+ }
#endif
F 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.h
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);
F diff --git a/src/frontend/lexer.c b/src/frontend/lexer.c --- a/src/frontend/lexer.c +++ b/src/frontend/lexer.c
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))
F diff --git a/src/frontend/parser.c b/src/frontend/parser.c --- a/src/frontend/parser.c +++ b/src/frontend/parser.c
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))
{
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_Event
F diff --git a/src/main.c b/src/main.c --- a/src/main.c +++ b/src/main.c
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)
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
F diff --git a/src/program/program.c b/src/program/program.c --- a/src/program/program.c +++ b/src/program/program.c
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));
}
F diff --git a/src/program/program.h b/src/program/program.h --- a/src/program/program.h +++ b/src/program/program.h
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);
F diff --git a/tests/.test5.swp b/tests/.test5.swp new file mode 100644
B Binary files /dev/null and b/tests/.test5.swp differ
F diff --git a/tests/test4 b/tests/test4 --- a/tests/test4 +++ b/tests/test4
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;
];
];
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;
+ ];
+ ];