/* scivi - visualization plugin for XMMS * Copyright (C) 2003 Vitaly V. Bursov * * 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; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ %{ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "mathcompile.h" #include "common.h" #if 0 # define YYDEBUG 1 # define YYERROR_VERBOSE 1 #endif #define ERR scivi_complier_error #define YYPARSE_PARAM p int mathlex(); void matherror(const char *s){dprintf("bison: parse error: %s\n",s);} %} %union { struct { int line; /* union'ify these */ void *exp; float num; char *str; /* buffer is malloc'd by code in lex-file */ } d; } %token EOS EOL %token KW_IF KW_ELSE %token KW_FOR KW_DO KW_WHILE KW_BREAK KW_CONTINUE %right SY_ASSGIN SY_ASSGIN_PLUS SY_ASSGIN_MIN SY_ASSGIN_DIV SY_ASSGIN_MUL %left NUM %left VAR FUNC %left SY_GR SY_LS SY_GE SY_LE SY_EQ SY_NEQ %left SY_OR SY_AND SY_XOR SY_OROR SY_ANDAND %left '+' '-' %left '/' '*' SY_MOD %left NEG SY_NOT SY_LNOT %start begin %type expr optexpr %type vararray funct %type stmt stmtif stmtwhile stmtdo stmtfor /*%type fun$1, parms*/ /* Bison 1.875 EXPERIMENTAL feature */ /* d.str */ %destructor { if (($$) != NULL) free($$); } VAR FUNC /* d.exp */ %destructor { if (($$) != NULL) MATH(expr_free)($$); } expr optexpr vararray funct stmt stmtif stmtwhile stmtdo stmtfor /* if/else conflict */ %expect 1 %% begin: stmts EOS { YYACCEPT; } error EOS { eprintf("2: parse error\n"); yyerrok; YYACCEPT; } ; /**************/ stmts: stmt | stmts stmt ; stmt: expr EOL { MATH(end_of_statement)($1, p, $1); } | stmtif | stmtwhile | stmtdo EOL | stmtfor | KW_BREAK EOL { MATH(sbreak)($1, p); } | KW_CONTINUE EOL { MATH(scontinue)($1, p); } | error EOL { ERR("%d: Parse error\n", $1); yyerrok; $$ = NULL; } | error EOS { ERR("%d: Parse error. Missing semicolon?\n", $1); yyerrok; $$ = NULL; } ; braced: stmt | '{' '}' { MATH(nop)($1, p); } | '{' stmts '}' | '{' error '}' ; /**************/ stmtif: KW_IF '(' expr ')' { MATH(stmt_if)($1, &p, $3); } braced stmtifelse { $$ = MATH(stmt_if_end)(0, &p); } ; stmtifelse: /* no else */ | KW_ELSE { MATH(stmt_if_else)(0, &p); } braced ; /**************/ stmtwhile: KW_WHILE '(' expr ')' { MATH(stmt_loop_start)($1, &p); } braced { $$ = MATH(stmt_while_end)(0, &p, $3); } ; /**************/ stmtdo: KW_DO { MATH(stmt_loop_start)($1, &p); } braced KW_WHILE '(' expr ')' { $$ = MATH(stmt_do_end)(0, &p, $6); } ; /**************/ stmtfor: KW_FOR '(' optexpr semicolon optexpr semicolon optexpr ')' { MATH(stmt_loop_start)($1, &p); } braced { $$ = MATH(stmt_for_end)(0, &p, $3, $5, $7); } ; semicolon: EOL ; /**************/ optexpr: /* none */ { $$ = NULL; } | expr ; expr: NUM { $$ = MATH(number)($1, $1); } | VAR { $$ = MATH(variable)($1, $1); } | vararray { $$ = $1; } | funct { $$ = $1; } | VAR SY_ASSGIN expr { $$ = MATH(var_assgn)($2, p, $1, $3); } | VAR SY_ASSGIN_PLUS expr { $$ = MATH(var_assgn_plus)($2, p, $1, $3); } | VAR SY_ASSGIN_MIN expr { $$ = MATH(var_assgn_min)($2, p, $1, $3); } | VAR SY_ASSGIN_DIV expr { $$ = MATH(var_assgn_div)($2, p, $1, $3); } | VAR SY_ASSGIN_MUL expr { $$ = MATH(var_assgn_mul)($2, p, $1, $3); } | vararray SY_ASSGIN expr { $$ = MATH(vararray_assgn)($2, p, $1, $3); } | vararray SY_ASSGIN_PLUS expr { $$ = MATH(vararray_assgn_plus)($2, p, $1, $3); } | vararray SY_ASSGIN_MIN expr { $$ = MATH(vararray_assgn_min)($2, p, $1, $3); } | vararray SY_ASSGIN_DIV expr { $$ = MATH(vararray_assgn_div)($2, p, $1, $3); } | vararray SY_ASSGIN_MUL expr { $$ = MATH(vararray_assgn_mul)($2, p, $1, $3); } | expr SY_OR expr { $$ = MATH(or)($2, p, $1, $3); } | SY_NOT expr { $$ = MATH(not)($1, p, $2); } | SY_LNOT expr { $$ = MATH(lnot)($1, p, $2); } | expr SY_AND expr { $$ = MATH(and)($2, p, $1, $3); } | expr SY_XOR expr { $$ = MATH(xor)($2, p, $1, $3); } | expr SY_MOD expr { $$ = MATH(mod )($2, p, $1, $3); } | expr SY_OROR expr { $$ = MATH(oror)($2, p, $1, $3); } | expr SY_ANDAND expr { $$ = MATH(andand)($2, p, $1, $3); } | expr SY_GR expr { $$ = MATH(gr)($2, p, $1, $3); } | expr SY_LS expr { $$ = MATH(ls)($2, p, $1, $3); } | expr SY_GE expr { $$ = MATH(ge)($2, p, $1, $3); } | expr SY_LE expr { $$ = MATH(le)($2, p, $1, $3); } | expr SY_EQ expr { $$ = MATH(eq)($2, p, $1, $3); } | expr SY_NEQ expr { $$ = MATH(neq)($2, p, $1, $3); } | expr '+' expr { $$ = MATH(plus)($2, p, $1, $3); } | expr '-' expr { $$ = MATH(minus)($2, p, $1, $3); } | '-' expr %prec NEG { $$ = MATH(negate)($1, p, $2); } | expr '/' expr { $$ = MATH(divide)($2, p, $1, $3); } | expr '*' expr { $$ = MATH(multiply)($2, p, $1, $3); } | '(' expr ')' { $$ = $2; } | '(' error ')' { $$ = NULL; } ; /**************/ funct: FUNC '(' { MATH(funct_start)($1, &p); } functoptprms ')' { $$ = MATH(funct)(0, &p, $1); } ; functoptprms: /**/ | functprms ; functprms: functprm | functprms ',' functprm ; functprm: expr { MATH(end_of_statement)($1, p, $1); } ; /**************/ vararray: VAR { MATH(array_start)($1, &p); } varaind { $$ = MATH(array)(0, &p, $1); } ; varaind: varainde | varaind varainde ; varainde: '[' expr ']' { MATH(end_of_statement)($2, p, $2); } | '[' error ']' ; %%