1 %{ 2 /* For printf() */ 3 #include <stdio.h> 4 5 /* Proformas for functions we define below... */ 6 void yyerror(char *s); 7 int yylex(void); 8 9 /* Specific for here... */ 10 double vbltable[26]; 11 %} 12 13 %union { 14 double dval; 15 int vblno; 16 } 17 18 %token <vblno> NAME 19 %token <dval> NUMBER 20 %left '-' '+' 21 %left '*' '/' 22 %nonassoc UMINUS 23 24 %type <dval> expression 25 %% 26 statement_list: statement '\n' 27 | statement_list statement '\n' 28 ; 29 30 statement: NAME '=' expression { vbltable[$1] = $3; } 31 | expression { printf("= %g\n", $1); } 32 ; 33 34 expression: expression '+' expression { $$ = $1 + $3; } 35 | expression '-' expression { $$ = $1 - $3; } 36 | expression '*' expression { $$ = $1 * $3; } 37 | expression '/' expression 38 { if($3 == 0.0) 39 yyerror("divide by zero"); 40 else 41 $$ = $1 / $3; 42 } 43 | '-' expression %prec UMINUS { $$ = -$2; } 44 | '(' expression ')' { $$ = $2; } 45 | NUMBER 46 | NAME { $$ = vbltable[$1]; } 47 ; 48 %% 49 /* An optional but friendlier yyerror function... */ 50 void yyerror(char *s) 51 { 52 extern int yylineno; // defined and maintained in lex 53 extern char *yytext; // defined and maintained in lex 54 fprintf(stderr, "ERROR: %s at symbol '%s' on line %d\n", s, 55 yytext, yylineno); 56 }