%name cl_ucsim_parser %{ #include "cmdlexcl.h" #include "memcl.h" #include "globals.h" #include "stypes.h" %} %pure_parser %define INHERIT : public cl_base %define MEMBERS class cl_ucsim_lexer *lexer_object;\ virtual ~YY_cl_ucsim_parser_CLASS(void) { delete lexer_object; } %define CONSTRUCTOR_PARAM \ class cl_ucsim_lexer *the_lexer %define CONSTRUCTOR_CODE \ lexer_object= the_lexer; %token PTOK_PLUS PTOK_MINUS PTOK_ASTERIX PTOK_SLASH PTOK_EQUAL %token PTOK_LEFT_PAREN PTOK_RIGHT_PAREN %token PTOK_LEFT_BRACKET PTOK_RIGHT_BRACKET %token PTOK_DOT PTOK_AMPERSAND %token PTOK_MEMORY_OBJECT %token PTOK_MEMORY %token PTOK_NUMBER %token PTOK_BIT %right PTOK_EQUAL %left PTOK_MINUS PTOK_PLUS %left PTOK_ASTERIX PTOK_SLASH %nonassoc UNARYMINUS PTOK_AMPERSAND %nonassoc PTOK_LEFT_PAREN PTOK_RIGHT_PAREN %type ucsim_grammar assignment expression address_of_expression %type memory %type bit %union { long number; class cl_memory *memory_object; struct { class cl_memory *memory; long address; } memory; struct { class cl_memory *memory; long mem_address, bit_address; long mask; } bit; } %% ucsim_grammar: expression { application->dd_printf("%d\n", $1); } ; assignment: memory PTOK_EQUAL expression { $1.memory->write($1.address, $3); $$= $3; } | bit PTOK_EQUAL expression { if ($3) { $1.memory->write($1.mem_address, $1.memory->read($1.mem_address) | $1.mask); $$= 1; } else { $1.memory->write($1.mem_address, $1.memory->read($1.mem_address) & ~($1.mask)); $$= 0; } } ; expression: assignment { $$= $1; } | expression PTOK_PLUS expression { $$= $1 + $3; } | expression PTOK_MINUS expression { $$= $1 - $3; } | expression PTOK_ASTERIX expression { $$= $1 * $3; } | expression PTOK_SLASH expression { if ($3 == 0) yyerror((char *)"Divide by zero"); else $$= $1 / $3; } | PTOK_MINUS expression %prec UNARYMINUS { $$= -$2; } | address_of_expression { $$= $1; } | PTOK_LEFT_PAREN expression PTOK_RIGHT_PAREN { $$= $2; } | PTOK_NUMBER { $$= $1; } | memory { $$= $1.memory->read($1.address); } | bit { $$= ($1.memory->read($1.mem_address) & $1.mask)?1:0; } ; address_of_expression: PTOK_AMPERSAND memory { $$= $2.address; } | PTOK_AMPERSAND bit { $$= $2.bit_address; if ($$ < 0) { yyerror((char *)"Bit has no address."); $$= 0; } } ; memory: PTOK_MEMORY | PTOK_MEMORY_OBJECT PTOK_LEFT_BRACKET expression PTOK_RIGHT_BRACKET { $$.memory= $1; $$.address= $3; } bit: PTOK_BIT | memory PTOK_DOT expression { $$.memory= $1.memory; $$.mem_address= $1.address; $$.mask= 1 << $3; $$.bit_address= -1; class cl_uc *uc= application->get_uc(); if (uc) $$.bit_address= uc->bit_address($1.memory, $1.address, $3); } ; %% int YY_cl_ucsim_parser_CLASS::yylex(YY_cl_ucsim_parser_STYPE *yylval) { lexer_object->activate_lexer_to_parse_into(yylval); return(lexer_object->yylex()); } void YY_cl_ucsim_parser_CLASS::yyerror(char *msg) { application->dd_printf("Parser error: %s\n", msg); }