1234949Sbapt%{
2234949Sbapt# include <stdio.h>
3234949Sbapt# include <ctype.h>
4234949Sbapt
5234949Sbaptint regs[26];
6234949Sbaptint base;
7234949Sbapt
8234949Sbaptint yylex(void);
9234949Sbaptstatic void yyerror(const char *s);
10234949Sbapt
11234949Sbapt%}
12234949Sbapt
13234949Sbapt%start list
14234949Sbapt
15234949Sbapt%token OP_ADD "ADD"
16234949Sbapt%token OP_SUB "SUB"
17234949Sbapt%token OP_MUL "MUL"
18234949Sbapt%token OP_DIV "DIV"
19234949Sbapt%token OP_MOD "MOD"
20234949Sbapt%token OP_AND "AND"
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 OP_ADD expr
47234949Sbapt            {  $$ = $1 + $3; }
48234949Sbapt      |  expr OP_SUB expr
49234949Sbapt            {  $$ = $1 - $3; }
50234949Sbapt      |  expr OP_MUL expr
51234949Sbapt            {  $$ = $1 * $3; }
52234949Sbapt      |  expr OP_DIV expr
53234949Sbapt            {  $$ = $1 / $3; }
54234949Sbapt      |  expr OP_MOD expr
55234949Sbapt            {  $$ = $1 % $3; }
56234949Sbapt      |  expr OP_AND expr
57234949Sbapt            {  $$ = $1 & $3; }
58234949Sbapt      |  expr '|' expr
59234949Sbapt            {  $$ = $1 | $3; }
60234949Sbapt      |  OP_SUB 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
75234949Sbaptint
76234949Sbaptmain (void)
77234949Sbapt{
78234949Sbapt    while(!feof(stdin)) {
79234949Sbapt	yyparse();
80234949Sbapt    }
81234949Sbapt    return 0;
82234949Sbapt}
83234949Sbapt
84234949Sbaptstatic void
85234949Sbaptyyerror(const char *s)
86234949Sbapt{
87234949Sbapt    fprintf(stderr, "%s\n", s);
88234949Sbapt}
89234949Sbapt
90234949Sbaptint
91234949Sbaptyylex(void) {
92234949Sbapt	/* lexical analysis routine */
93234949Sbapt	/* returns LETTER for a lower case letter, yylval = 0 through 25 */
94234949Sbapt	/* return DIGIT for a digit, yylval = 0 through 9 */
95234949Sbapt	/* all other characters are returned immediately */
96234949Sbapt
97234949Sbapt    int c;
98234949Sbapt
99234949Sbapt    while( (c=getchar()) == ' ' )   { /* skip blanks */ }
100234949Sbapt
101234949Sbapt    /* c is now nonblank */
102234949Sbapt
103234949Sbapt    if( islower( c )) {
104234949Sbapt	yylval = c - 'a';
105234949Sbapt	return ( LETTER );
106234949Sbapt    }
107234949Sbapt    if( isdigit( c )) {
108234949Sbapt	yylval = c - '0';
109234949Sbapt	return ( DIGIT );
110234949Sbapt    }
111234949Sbapt    return( c );
112234949Sbapt}
113