1234949Sbapt%parse-param { int regs[26] }
2234949Sbapt%parse-param { int *base }
3234949Sbapt
4234949Sbapt%lex-param { int *base }
5234949Sbapt
6234949Sbapt%{
7234949Sbapt# include <stdio.h>
8234949Sbapt# include <ctype.h>
9234949Sbapt
10234949Sbapt#ifdef YYBISON
11234949Sbapt#define YYLEX_PARAM base
12234949Sbapt#define YYLEX_DECL() yylex(int *YYLEX_PARAM)
13234949Sbapt#define YYERROR_DECL() yyerror(int regs[26], int *base, const char *s)
14234949Sbaptint YYLEX_DECL();
15234949Sbaptstatic void YYERROR_DECL();
16234949Sbapt#endif
17234949Sbapt
18234949Sbapt%}
19234949Sbapt
20234949Sbapt%start list
21234949Sbapt
22234949Sbapt%token DIGIT LETTER
23234949Sbapt
24234949Sbapt%left '|'
25234949Sbapt%left '&'
26234949Sbapt%left '+' '-'
27234949Sbapt%left '*' '/' '%'
28234949Sbapt%left UMINUS   /* supplies precedence for unary minus */
29234949Sbapt
30234949Sbapt%% /* beginning of rules section */
31234949Sbapt
32234949Sbaptlist  :  /* empty */
33234949Sbapt      |  list stat '\n'
34234949Sbapt      |  list error '\n'
35234949Sbapt            {  yyerrok ; }
36234949Sbapt      ;
37234949Sbapt
38234949Sbaptstat  :  expr
39234949Sbapt            {  printf("%d\n",$1);}
40234949Sbapt      |  LETTER '=' expr
41234949Sbapt            {  regs[$1] = $3; }
42234949Sbapt      ;
43234949Sbapt
44234949Sbaptexpr  :  '(' expr ')'
45234949Sbapt            {  $$ = $2; }
46234949Sbapt      |  expr '+' expr
47234949Sbapt            {  $$ = $1 + $3; }
48234949Sbapt      |  expr '-' expr
49234949Sbapt            {  $$ = $1 - $3; }
50234949Sbapt      |  expr '*' expr
51234949Sbapt            {  $$ = $1 * $3; }
52234949Sbapt      |  expr '/' expr
53234949Sbapt            {  $$ = $1 / $3; }
54234949Sbapt      |  expr '%' expr
55234949Sbapt            {  $$ = $1 % $3; }
56234949Sbapt      |  expr '&' expr
57234949Sbapt            {  $$ = $1 & $3; }
58234949Sbapt      |  expr '|' expr
59234949Sbapt            {  $$ = $1 | $3; }
60234949Sbapt      |  '-' expr %prec UMINUS
61234949Sbapt            {  $$ = - $2; }
62234949Sbapt      |  LETTER
63234949Sbapt            {  $$ = regs[$1]; }
64234949Sbapt      |  number
65234949Sbapt      ;
66234949Sbapt
67234949Sbaptnumber:  DIGIT
68234949Sbapt         {  $$ = $1; (*base) = ($1==0) ? 8 : 10; }
69234949Sbapt      |  number DIGIT
70234949Sbapt         {  $$ = (*base) * $1 + $2; }
71234949Sbapt      ;
72234949Sbapt
73234949Sbapt%% /* start of programs */
74234949Sbapt
75234949Sbapt#ifdef YYBYACC
76234949Sbaptextern int YYLEX_DECL();
77234949Sbapt#endif
78234949Sbapt
79234949Sbaptint
80234949Sbaptmain (void)
81234949Sbapt{
82234949Sbapt    int regs[26];
83234949Sbapt    int base = 10;
84234949Sbapt
85234949Sbapt    while(!feof(stdin)) {
86234949Sbapt	yyparse(regs, &base);
87234949Sbapt    }
88234949Sbapt    return 0;
89234949Sbapt}
90234949Sbapt
91264803Sbapt#define UNUSED(x) ((void)(x))
92264803Sbapt
93234949Sbaptstatic void
94234949SbaptYYERROR_DECL()
95234949Sbapt{
96264803Sbapt    UNUSED(regs); /* %parse-param regs is not actually used here */
97264803Sbapt    UNUSED(base); /* %parse-param base is not actually used here */
98234949Sbapt    fprintf(stderr, "%s\n", s);
99234949Sbapt}
100234949Sbapt
101234949Sbaptint
102234949SbaptYYLEX_DECL()
103234949Sbapt{
104234949Sbapt	/* lexical analysis routine */
105234949Sbapt	/* returns LETTER for a lower case letter, yylval = 0 through 25 */
106234949Sbapt	/* return DIGIT for a digit, yylval = 0 through 9 */
107234949Sbapt	/* all other characters are returned immediately */
108234949Sbapt
109234949Sbapt    int c;
110234949Sbapt
111234949Sbapt    while( (c=getchar()) == ' ' )   { /* skip blanks */ }
112234949Sbapt
113234949Sbapt    /* c is now nonblank */
114234949Sbapt
115234949Sbapt    if( islower( c )) {
116234949Sbapt	yylval = c - 'a';
117234949Sbapt	return ( LETTER );
118234949Sbapt    }
119234949Sbapt    if( isdigit( c )) {
120234949Sbapt	yylval = (c - '0') % (*base);
121234949Sbapt	return ( DIGIT );
122234949Sbapt    }
123234949Sbapt    return( c );
124234949Sbapt}
125