/* * TCC - TRD Configuration Compiler * Author: Jan de Cuveland * Kirchhoff-Institut fuer Physik * Extended by: * Tom Dietel * IKP Muenster * */ /* Everything up to "%}" is copied verbatim to the top of yac.c. (output file)*/ %{ #include #include #include #include #include "tcc.h" #include "parser.h" int yylex(void); void yyerror(const char *s); extern char * current_filename; 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; float fval; 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 FLOAT %token VAR FNCT %token CONST ASMVAR %token RESTRICT %token SECTOR STACK LAYER ROCS %token WRITE NOP READ EXPECT READSEQ PRETRIGGER WAIT // tokens used for multiple things %token ALL DEFAULT LOGLEVEL RUN GET %token BRIDGE RESET // LTU/tracklet settings %token TRACKLET MINPT BFIELD OMEGATAU DRIFTBINS APPLY %token SCALEQ0 SCALEQ1 TRACKLENGTHCORR TILTEDCORR // CE tests %token CETEST NI ORI SHUTDOWN LASERID NIFAST DMM DDD IMM NISINGLE PING // rstate %token RSTATE GSMSTATE NISTATE EVCNT PTRGCNT LC0CNT LC1CNT LC2CNT LC3CNT // loglevels %token ECRITICAL EERROR EWARN EINFO EDEBUG %type exp %type fexp %type roc_rest_exp %type sector_rest_exp %type stack_rest_exp %type layer_rest_exp %type rstate_flags %type loglevel_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; } | RESTRICT roc_rest_exp { write_word(18, 0, 0, $2); } | RESTRICT ALL ROCS { write_word(18, 0, 0, 0x1FFFFFFF); } | TRACKLET MINPT fexp { write_word(27, 1, 0, (int)(1000.*$3)); } | TRACKLET BFIELD fexp { write_word(27, 1, 1, (int)(1000.*$3)); } | TRACKLET OMEGATAU fexp { write_word(27, 1, 2, (int)(1000000.*$3)); } | TRACKLET DRIFTBINS fexp { write_word(27, 1, 3, (int)( (1<<5) * $3)); } | TRACKLET APPLY { write_word(27, 0, 0, 0); } | TRACKLET SCALEQ0 exp { write_word(27, 1, 4, $3); } | TRACKLET SCALEQ1 exp { write_word(27, 1, 5, $3); } | TRACKLET TRACKLENGTHCORR exp { write_word(27, 1, 6, $3); } | TRACKLET TILTEDCORR exp { write_word(27, 1, 7, $3); } | RSTATE RUN { write_word(23,1,0,0); } | RSTATE GET { write_word(23,1,1,0); } | RSTATE GET rstate_flags { write_word(23,1,1,$3); } | RSTATE LOGLEVEL loglevel_exp { write_word(23,1,2,$3); } | CETEST NI { write_word(21, 0, 0, 0); } | CETEST ORI { write_word(21, 0, 0, 1); } | CETEST BRIDGE { write_word(21, 0, 0, 2); } | CETEST RESET { write_word(21, 0, 0, 3); } | CETEST SHUTDOWN { write_word(21, 0, 0, 4); } | CETEST LASERID { write_word(21, 0, 0, 5); } | CETEST NIFAST { write_word(21, 0, 0, 6); } | CETEST DMM { write_word(21, 0, 0, 7); } | CETEST DDD { write_word(21, 0, 0, 8); } | CETEST IMM { write_word(21, 0, 0, 9); } | CETEST NISINGLE { write_word(21, 0, 0, 10); } | CETEST PING { write_word(21, 0, 0, 11); } ; 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"); if ($1->state == stASM) yyerror("cannot change assembler variable"); $1->state = stSET; } } | CONST VAR '=' exp { $$ = $4; if (active) { $2->value.var = $4; if ($2->state != stUNSET) yyerror("const symbol already used"); $2->state = stCONST; } } | ASMVAR VAR '=' exp { $$ = $4; if (active) { $2->value.var = $4; if ($2->state != stUNSET) yyerror("asm symbol already used"); $2->state = stASM; } } | 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; } ; fexp: FLOAT { $$ = $1; } | fexp '+' fexp { $$ = $1 + $3; } | fexp '-' fexp { $$ = $1 - $3; } | fexp '*' fexp { $$ = $1 * $3; } | fexp '/' fexp { $$ = $1 / $3; } | '+' fexp %prec SGN { $$ = $2; } | '-' fexp %prec SGN { $$ = -$2; } ; roc_rest_exp : sector_rest_exp { $$ = $1 | 0x7FF; } | stack_rest_exp { $$ = $1 | 0x1FFFF83F; } | layer_rest_exp { $$ = $1 | 0x1FFFFFC0; } | roc_rest_exp roc_rest_exp {$$ = $1 & $2; } sector_rest_exp: SECTOR NUM { $$ = (1<<($2+11)); } | sector_rest_exp ',' NUM { $$ |= (1<<($3+11)); } stack_rest_exp: STACK NUM { $$ = (1<<($2+6)); } | stack_rest_exp ',' NUM { $$ |= (1<<($3+6)); } layer_rest_exp: LAYER NUM { $$ = (1<<$2); } | layer_rest_exp ',' NUM { $$ |= (1<<$3); } /* rstate flags */ rstate_flags : rstate_flags '|' rstate_flags { $$ = $1 | $3; } | GSMSTATE {$$ = 0x01; } | NISTATE {$$ = 0x02; } | EVCNT {$$ = 0x04; } | PTRGCNT {$$ = 0x08; } | LC0CNT {$$ = 0x10; } | LC1CNT {$$ = 0x20; } | LC2CNT {$$ = 0x40; } | LC3CNT {$$ = 0x80; } | ALL {$$ = 0xFF; } | DEFAULT {$$ = 0;} /* log levels */ loglevel_exp : ECRITICAL { $$ = 0; } | EERROR { $$ = 10; } | EWARN { $$ = 20; } | EINFO { $$ = 30; } | EDEBUG { $$ = 40; } eol: '\n' | '\r' '\n' ; %% /* Called by yyparse on error */ void yyerror (const char *s) { extern int yylineno; extern char* yytext; fprintf(stderr, "%s:%d: ERROR: %s at symbol '%s'\n", current_filename, yylineno, s, yytext); exit(1); }