/****************************************************************************************/ /* */ /* "compute.y" */ /* */ /* "yacc" input for a simple computer. It is suitable to compute the constant */ /* expressions in "IDCT.tmpl". */ /* */ /*--------------------------------------------------------------------------------------*/ /* */ /* This program is free software; you can redistribute it and/or modify it under the */ /* terms of the GNU General Public License as published by the Free Software */ /* Foundation; either version 2 of the License, or (at your option) any later version. */ /* */ /* This program is distributed in the hope that it will be useful, but WITHOUT ANY */ /* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A */ /* PARTICULAR PURPOSE. See the GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License along with this */ /* program; (See "LICENSE.GPL"). If not, write to the Free Software Foundation, Inc., */ /* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* */ /*--------------------------------------------------------------------------------------*/ /* */ /* If the program runs as Java applet it isn't "interactive" in the sense of the GNU */ /* General Public License. So paragraph 2c doesn't apply. */ /* */ /****************************************************************************************/ %{ #include #include /* cos, sin ... */ extern double res; extern int line_nr, pos; extern char equation[]; static struct f_tab_str{ /* table of mathematical functions */ char *fname; double (*fptr)(); } ftab[] = { "acos", acos, "asin", asin, "atan", atan, "atan2", atan2, "cos", cos, "sin", sin, "tan", tan, "cosh", cosh, "sinh", sinh, "tanh", tanh, "exp", exp, "frexp", frexp, "ldexp", ldexp, "log", log, "log10", log10, "modf", modf, "sqrt", sqrt, "ceil", ceil, "fabs", fabs, "floor", floor, "fmod", fmod, NULL, NULL}; %} /*++++++++++ The following declaration defines the type of the ++++++++++++*/ /*+++++++++++++++ parser stack and of the $... variables ++++++++++++++++++*/ %union { double dwert; char *str; } /*+++++++++++++ precedence and associativities of the operators ++++++*/ %left '-' '+' %left '*' '/' %right '^' %left UNAER /* special precedence for unary opeartors */ %token NUMBER /* token with attribut double */ %token NAME /* token with attribut char* */ /*++++++++++++ definition of the types of non-tokens +++++++++++++++*/ %type expression %start all /* start symbol of the grammer */ %% all: expression {res = $1; /* pass the result to the (global) variable "res" */} | error ; expression : NUMBER /* $$ = $1 is the default action ! */ | expression '+' expression {$$ = $1 + $3;} | expression '-' expression {$$ = $1 - $3;} | expression '*' expression {$$ = $1 * $3;} | expression '/' expression {if ($3 != 0.0) { $$ = $1 / $3; } else { fprintf(stderr, "line %d: division by zero\n", pos); $$= 0; } } | expression '^' expression {$$ = pow($1, $3);} | '-' expression %prec UNAER {$$ = -$2;} | '+' expression %prec UNAER {$$ = $2;} | '(' expression ')' {$$ = $2;} | NAME '(' expression ')' {struct f_tab_str *ptr; int found; ptr = ftab; found = 0; while (!found && ptr->fname) { if (found = !strcmp(ptr->fname, $1)) { $$ = (*(ptr->fptr))($3); found = 1; } ptr++; } if (!found) { $$ = 0.0; fprintf(stderr, "function %s unknown\n", $1); } free($1); /* no longer used */ } ; %% /* The function "yyerror" is called in error case. Its */ /* implementation is simpel: It prints the string "s" and shows */ /* the line and column of the error. ("pos" is updated by */ /* "yylex()". */ yyerror(s) char *s; { fprintf(stderr, "line %d:%s\nposition %d: %s\n", line_nr, equation, pos, s); }