1%parse-param { int regs[26] }
2%parse-param { int *base }
3
4%lex-param { int *base }
5
6%{
7# include <stdio.h>
8# include <ctype.h>
9
10#ifdef YYBISON
11#define YYLEX_PARAM base
12#define YYLEX_DECL() yylex(int *YYLEX_PARAM)
13#define YYERROR_DECL() yyerror(int regs[26], int *base, const char *s)
14int YYLEX_DECL();
15static void YYERROR_DECL();
16#endif
17
18%}
19
20%start list
21
22%token DIGIT LETTER
23
24%left '|'
25%left '&'
26%left '+' '-'
27%left '*' '/' '%'
28%left UMINUS   /* supplies precedence for unary minus */
29
30%% /* beginning of rules section */
31
32list  :  /* empty */
33      |  list stat '\n'
34      |  list error '\n'
35            {  yyerrok ; }
36      ;
37
38stat  :  expr
39            {  printf("%d\n",$1);}
40      |  LETTER '=' expr
41            {  regs[$1] = $3; }
42      ;
43
44expr  :  '(' expr ')'
45            {  $$ = $2; }
46      |  expr '+' expr
47            {  $$ = $1 + $3; }
48      |  expr '-' expr
49            {  $$ = $1 - $3; }
50      |  expr '*' expr
51            {  $$ = $1 * $3; }
52      |  expr '/' expr
53            {  $$ = $1 / $3; }
54      |  expr '%' expr
55            {  $$ = $1 % $3; }
56      |  expr '&' expr
57            {  $$ = $1 & $3; }
58      |  expr '|' expr
59            {  $$ = $1 | $3; }
60      |  '-' expr %prec UMINUS
61            {  $$ = - $2; }
62      |  LETTER
63            {  $$ = regs[$1]; }
64      |  number
65      ;
66
67number:  DIGIT
68         {  $$ = $1; (*base) = ($1==0) ? 8 : 10; }
69      |  number DIGIT
70         {  $$ = (*base) * $1 + $2; }
71      ;
72
73%% /* start of programs */
74
75#ifdef YYBYACC
76extern int YYLEX_DECL();
77#endif
78
79int
80main (void)
81{
82    int regs[26];
83    int base = 10;
84
85    while(!feof(stdin)) {
86	yyparse(regs, &base);
87    }
88    return 0;
89}
90
91#define UNUSED(x) ((void)(x))
92
93static void
94YYERROR_DECL()
95{
96    UNUSED(regs); /* %parse-param regs is not actually used here */
97    UNUSED(base); /* %parse-param base is not actually used here */
98    fprintf(stderr, "%s\n", s);
99}
100
101int
102YYLEX_DECL()
103{
104	/* lexical analysis routine */
105	/* returns LETTER for a lower case letter, yylval = 0 through 25 */
106	/* return DIGIT for a digit, yylval = 0 through 9 */
107	/* all other characters are returned immediately */
108
109    int c;
110
111    while( (c=getchar()) == ' ' )   { /* skip blanks */ }
112
113    /* c is now nonblank */
114
115    if( islower( c )) {
116	yylval = c - 'a';
117	return ( LETTER );
118    }
119    if( isdigit( c )) {
120	yylval = (c - '0') % (*base);
121	return ( DIGIT );
122    }
123    return( c );
124}
125