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 }