1235723Sbapt%parse-param { int regs[26] }
2235723Sbapt%parse-param { int *base }
3235723Sbapt
4235723Sbapt%lex-param { int *base }
5235723Sbapt
6235723Sbapt%{
7235723Sbapt# include <stdio.h>
8235723Sbapt# include <ctype.h>
9235723Sbapt
10235723Sbapt#ifdef YYBISON
11235723Sbapt#define YYLEX_PARAM base
12235723Sbapt#define YYLEX_DECL() yylex(int *YYLEX_PARAM)
13235723Sbapt#define YYERROR_DECL() yyerror(int regs[26], int *base, const char *s)
14235723Sbaptint YYLEX_DECL();
15235723Sbaptstatic void YYERROR_DECL();
16235723Sbapt#endif
17235723Sbapt
18235723Sbapt%}
19235723Sbapt
20235723Sbapt%start list
21235723Sbapt
22235723Sbapt%token DIGIT LETTER
23235723Sbapt
24235723Sbapt%left '|'
25235723Sbapt%left '&'
26235723Sbapt%left '+' '-'
27235723Sbapt%left '*' '/' '%'
28235723Sbapt%left UMINUS   /* supplies precedence for unary minus */
29235723Sbapt
30235723Sbapt%% /* beginning of rules section */
31235723Sbapt
32235723Sbaptlist  :  /* empty */
33235723Sbapt      |  list stat '\n'
34235723Sbapt      |  list error '\n'
35235723Sbapt            {  yyerrok ; }
36235723Sbapt      ;
37235723Sbapt
38235723Sbaptstat  :  expr
39235723Sbapt            {  printf("%d\n",$1);}
40235723Sbapt      |  LETTER '=' expr
41235723Sbapt            {  regs[$1] = $3; }
42235723Sbapt      ;
43235723Sbapt
44235723Sbaptexpr  :  '(' expr ')'
45235723Sbapt            {  $$ = $2; }
46235723Sbapt      |  expr '+' expr
47235723Sbapt            {  $$ = $1 + $3; }
48235723Sbapt      |  expr '-' expr
49235723Sbapt            {  $$ = $1 - $3; }
50235723Sbapt      |  expr '*' expr
51235723Sbapt            {  $$ = $1 * $3; }
52235723Sbapt      |  expr '/' expr
53235723Sbapt            {  $$ = $1 / $3; }
54235723Sbapt      |  expr '%' expr
55235723Sbapt            {  $$ = $1 % $3; }
56235723Sbapt      |  expr '&' expr
57235723Sbapt            {  $$ = $1 & $3; }
58235723Sbapt      |  expr '|' expr
59235723Sbapt            {  $$ = $1 | $3; }
60235723Sbapt      |  '-' expr %prec UMINUS
61235723Sbapt            {  $$ = - $2; }
62235723Sbapt      |  LETTER
63235723Sbapt            {  $$ = regs[$1]; }
64235723Sbapt      |  number
65235723Sbapt      ;
66235723Sbapt
67235723Sbaptnumber:  DIGIT
68235723Sbapt         {  $$ = $1; (*base) = ($1==0) ? 8 : 10; }
69235723Sbapt      |  number DIGIT
70235723Sbapt         {  $$ = (*base) * $1 + $2; }
71235723Sbapt      ;
72235723Sbapt
73235723Sbapt%% /* start of programs */
74235723Sbapt
75235723Sbapt#ifdef YYBYACC
76235723Sbaptextern int YYLEX_DECL();
77235723Sbapt#endif
78235723Sbapt
79235723Sbaptint
80235723Sbaptmain (void)
81235723Sbapt{
82235723Sbapt    int regs[26];
83235723Sbapt    int base = 10;
84235723Sbapt
85235723Sbapt    while(!feof(stdin)) {
86235723Sbapt	yyparse(regs, &base);
87235723Sbapt    }
88235723Sbapt    return 0;
89235723Sbapt}
90235723Sbapt
91235723Sbaptstatic void
92235723SbaptYYERROR_DECL()
93235723Sbapt{
94235723Sbapt    fprintf(stderr, "%s\n", s);
95235723Sbapt}
96235723Sbapt
97235723Sbaptint
98235723SbaptYYLEX_DECL()
99235723Sbapt{
100235723Sbapt	/* lexical analysis routine */
101235723Sbapt	/* returns LETTER for a lower case letter, yylval = 0 through 25 */
102235723Sbapt	/* return DIGIT for a digit, yylval = 0 through 9 */
103235723Sbapt	/* all other characters are returned immediately */
104235723Sbapt
105235723Sbapt    int c;
106235723Sbapt
107235723Sbapt    while( (c=getchar()) == ' ' )   { /* skip blanks */ }
108235723Sbapt
109235723Sbapt    /* c is now nonblank */
110235723Sbapt
111235723Sbapt    if( islower( c )) {
112235723Sbapt	yylval = c - 'a';
113235723Sbapt	return ( LETTER );
114235723Sbapt    }
115235723Sbapt    if( isdigit( c )) {
116235723Sbapt	yylval = (c - '0') % (*base);
117235723Sbapt	return ( DIGIT );
118235723Sbapt    }
119235723Sbapt    return( c );
120235723Sbapt}
121