/* C declarations */ /* vi: set et ts=4: */ %{ #include <stdio.h> #include <math.h> int base = 10; /* Prototypes */ static void yyerror(const char *); static int fac(int x); /* import from spascal.l */ extern int lineno; extern int yylex(void); %} /* Start symbol */ %start line /* Tokens */ %token DIGIT %token PI %token OPEN_PAREN CLOSE_PAREN %token '|' /* Tokens with precedence assigned */ /* The sooner the operator is defined, the lower its precedence */ %left '-' '+' %left '*' '/' '%' %left UMINUS %left '!' %right EXPONENT /* Rules */ %% line: | line stmt '\n' | line error '\n' { yyerrok; } ; stmt: expr { printf("%d\n",$1); } ; expr: OPEN_PAREN expr CLOSE_PAREN { $$ = $2; } | '|' expr '|' { $$ = (int)fabs((double)$2); } | expr '*' expr { $$ = $1 * $3; } | expr '/' expr { $$ = $1 / $3; } | expr '%' expr { $$ = $1 % $3; } | expr '-' expr { $$ = $1 - $3; } | expr '+' expr { $$ = $1 + $3; } | expr '!' { if ($1 < 0) { fprintf(stderr, "Negative values for faculty are undefined.\n"); YYERROR; } $$ = fac($1); } | expr EXPONENT expr { $$ = (int)pow((double)$1, (double)$3); } | '-' expr %prec UMINUS { $$ = -$2; } | number ; number: PI { $$ = 3; } | DIGIT { $$ = $1; } | number DIGIT { $$ = base * $1 + $2; } ; %% /* End of rules, more C code will follow now */ int main() { return yyparse(); } static void yyerror(const char *s) { fprintf(stderr, "%s\n",s); } int yywrap() { return(1); } int fac(int x) { return (x > 1) ? x*fac(x-1) : 1; }