1235723Sbapt%{
2235723Sbapt# include <stdio.h>
3235723Sbapt# include <ctype.h>
4235723Sbapt
5235723Sbaptint regs[26];
6235723Sbaptint base;
7235723Sbapt
8235723Sbaptint yylex(void);
9235723Sbaptstatic void yyerror(const char *s);
10235723Sbapt
11235723Sbapt%}
12235723Sbapt
13235723Sbapt%start list
14235723Sbapt
15235723Sbapt%token OP_ADD "ADD-operator"
16235723Sbapt%token OP_SUB "SUB-operator"
17235723Sbapt%token OP_MUL "MUL-operator"
18235723Sbapt%token OP_DIV "DIV-operator"
19235723Sbapt%token OP_MOD "MOD-operator"
20235723Sbapt%token OP_AND "AND-operator"
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 "ADD-operator" expr
47235723Sbapt            {  $$ = $1 + $3; }
48235723Sbapt      |  expr "SUB-operator" expr
49235723Sbapt            {  $$ = $1 - $3; }
50235723Sbapt      |  expr "MUL-operator" expr
51235723Sbapt            {  $$ = $1 * $3; }
52235723Sbapt      |  expr "DIV-operator" expr
53235723Sbapt            {  $$ = $1 / $3; }
54235723Sbapt      |  expr "MOD-operator" expr
55235723Sbapt            {  $$ = $1 % $3; }
56235723Sbapt      |  expr "AND-operator" expr
57235723Sbapt            {  $$ = $1 & $3; }
58235723Sbapt      |  expr '|' expr
59235723Sbapt            {  $$ = $1 | $3; }
60235723Sbapt      |  "SUB-operator" 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
75235723Sbaptint
76235723Sbaptmain (void)
77235723Sbapt{
78235723Sbapt    while(!feof(stdin)) {
79235723Sbapt	yyparse();
80235723Sbapt    }
81235723Sbapt    return 0;
82235723Sbapt}
83235723Sbapt
84235723Sbaptstatic void
85235723Sbaptyyerror(const char *s)
86235723Sbapt{
87235723Sbapt    fprintf(stderr, "%s\n", s);
88235723Sbapt}
89235723Sbapt
90235723Sbaptint
91235723Sbaptyylex(void) {
92235723Sbapt	/* lexical analysis routine */
93235723Sbapt	/* returns LETTER for a lower case letter, yylval = 0 through 25 */
94235723Sbapt	/* return DIGIT for a digit, yylval = 0 through 9 */
95235723Sbapt	/* all other characters are returned immediately */
96235723Sbapt
97235723Sbapt    int c;
98235723Sbapt
99235723Sbapt    while( (c=getchar()) == ' ' )   { /* skip blanks */ }
100235723Sbapt
101235723Sbapt    /* c is now nonblank */
102235723Sbapt
103235723Sbapt    if( islower( c )) {
104235723Sbapt	yylval = c - 'a';
105235723Sbapt	return ( LETTER );
106235723Sbapt    }
107235723Sbapt    if( isdigit( c )) {
108235723Sbapt	yylval = c - '0';
109235723Sbapt	return ( DIGIT );
110235723Sbapt    }
111235723Sbapt    return( c );
112235723Sbapt}
113