/* * TCC - TRD Configuration Compiler * Author: Jan de Cuveland * Kirchhoff-Institut fuer Physik * Date: December 15, 2003 */ /* Everything up to "%}" is copied verbatim to the top of yac.c. (output file)*/ %{ #include #include #include #include "tcc.h" #include "tcc.tab.h" int yylex(void); void yyerror(const char *s); int i; %} // Here we define the types and names of the components of YYSTYPE, which // is the type of the semantic portion of parse-stack entries. // union members for lexical values of tokens %union { int val; symrec *tptr; } // Specify in order of increasing precedence the names of the tokens, // their associativity, and which components of the union YYSTYPE // their lexical values will occupy. %token NUM %token VAR FNCT %token CONST %token RESTRICT %token WRITE RESET NOP READ EXPECT READSEQ PRETRIGGER WAIT BRIDGE %type exp %right '=' %left OR %left AND %left '|' %left '^' %left '&' %left EQ NE %left LT LE GT GE %left SHL SHR %left '+' '-' %left '*' '/' '%' %right '!' '~' INC DEC SGN %left '(' ')' // Specify the start symbol of the grammar. %start input %% // Specify the grammar rules and their associated semantic actions. input: /* empty */ | input line ; line: eol | stmt eol | stmt ';' | error eol { yyerrok; } ; /* VA : added the second wait format */ stmt: exp | WRITE exp ',' exp { write_word(10, 127, $2, $4); } | WRITE exp ',' exp ',' exp { write_word(10, $2, $4, $6); } | RESET { write_word(6, 127, 0, 0); } | RESET exp { write_word(6, $2, 0, 0); } | NOP { write_word(7, 127, 0, 0); } | READ exp ',' exp { write_word(9, $2, $4, 0); } | EXPECT exp ',' exp ',' exp { write_word(9, $2, $4, $6); } | READSEQ exp ',' exp ',' exp { for (i = 0; i < $6; i++) write_word(9, $2, $4+i, 0); } | PRETRIGGER exp { write_word(12, 127, 0, $2); } | WAIT exp { write_word(8, 127, 0, $2); } | WAIT exp ',' exp ',' exp { write_word(8, $6, $4, $2); } | BRIDGE exp ',' exp { write_word(4, $2, 0, $4); } | RESTRICT exp { active = $2; } ; exp: NUM { $$ = $1; } | VAR { $$ = $1->value.var; if (active) { if ($1->state == stUNSET) yyerror("uninitialized variable"); } } | VAR '=' exp { $$ = $3; if (active) { $1->value.var = $3; if ($1->state == stCONST) yyerror("cannot change const"); $1->state = stSET; } } | CONST VAR '=' exp { $$ = $4; if (active) { $2->value.var = $4; if ($2->state != stUNSET) yyerror("symbol already used"); $2->state = stCONST; } } | FNCT '(' exp ')' { $$ = (*($1->value.fnctptr))($3); } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | exp '%' exp { $$ = $1 % $3; } | '+' exp %prec SGN { $$ = $2; } | '-' exp %prec SGN { $$ = -$2; } | exp EQ exp { $$ = ($1 == $3); } | exp NE exp { $$ = ($1 != $3); } | exp LT exp { $$ = ($1 < $3); } | exp LE exp { $$ = ($1 <= $3); } | exp GT exp { $$ = ($1 > $3); } | exp GE exp { $$ = ($1 >= $3); } | exp OR exp { $$ = $1 || $3; } | exp AND exp { $$ = $1 && $3; } | exp '|' exp { $$ = $1 | $3; } | exp '^' exp { $$ = $1 ^ $3; } | exp '&' exp { $$ = $1 & $3; } | exp SHL exp { $$ = $1 << $3; } | exp SHR exp { $$ = $1 >> $3; } | '!' exp { $$ = ! $2; } | '~' exp { $$ = ~ $2; } | INC VAR { if (active) $$ = ++$2->value.var; } | VAR INC { if (active) $$ = $1->value.var++; } | DEC VAR { if (active) $$ = --$2->value.var; } | VAR DEC { if (active) $$ = $1->value.var--; } | '(' exp ')' { $$ = $2; } ; eol: '\n' | '\r' '\n' ; %% /* Called by yyparse on error */ void yyerror (const char *s) { extern int yylineno; extern char* yytext; fprintf(stderr, "ERROR: %s at symbol '%s' on line %d\n", s, yytext, yylineno); exit(1); }