1335640Shselasky%{
2335640Shselasky# include <stdio.h>
3335640Shselasky# include <ctype.h>
4335640Shselasky
5335640Shselaskyint regs[26];
6335640Shselaskyint base;
7335640Shselasky
8335640Shselaskyint yylex(void);
9335640Shselaskystatic void yyerror(const char *s);
10335640Shselasky
11335640Shselasky%}
12335640Shselasky
13335640Shselasky%start list
14335640Shselasky
15335640Shselasky%token OP_ADD "ADD"
16335640Shselasky%token OP_SUB "SUB"
17335640Shselasky%token OP_MUL "MUL"
18335640Shselasky%token OP_DIV "DIV"
19335640Shselasky%token OP_MOD "MOD"
20356341Scy%token OP_AND "AND"
21335640Shselasky
22335640Shselasky%token DIGIT LETTER
23335640Shselasky
24335640Shselasky%left '|'
25335640Shselasky%left '&'
26335640Shselasky%left '+' '-'
27335640Shselasky%left '*' '/' '%'
28335640Shselasky%left UMINUS   /* supplies precedence for unary minus */
29335640Shselasky
30335640Shselasky%% /* beginning of rules section */
31335640Shselasky
32335640Shselaskylist  :  /* empty */
33335640Shselasky      |  list stat '\n'
34335640Shselasky      |  list error '\n'
35335640Shselasky            {  yyerrok ; }
36335640Shselasky      ;
37335640Shselasky
38335640Shselaskystat  :  expr
39335640Shselasky            {  printf("%d\n",$1);}
40335640Shselasky      |  LETTER '=' expr
41335640Shselasky            {  regs[$1] = $3; }
42335640Shselasky      ;
43335640Shselasky
44335640Shselaskyexpr  :  '(' expr ')'
45335640Shselasky            {  $$ = $2; }
46335640Shselasky      |  expr "ADD" expr
47335640Shselasky            {  $$ = $1 + $3; }
48335640Shselasky      |  expr "SUB" expr
49335640Shselasky            {  $$ = $1 - $3; }
50335640Shselasky      |  expr "MUL" expr
51335640Shselasky            {  $$ = $1 * $3; }
52335640Shselasky      |  expr "DIV" expr
53335640Shselasky            {  $$ = $1 / $3; }
54335640Shselasky      |  expr "MOD" expr
55335640Shselasky            {  $$ = $1 % $3; }
56335640Shselasky      |  expr "AND" expr
57335640Shselasky            {  $$ = $1 & $3; }
58335640Shselasky      |  expr '|' expr
59335640Shselasky            {  $$ = $1 | $3; }
60356341Scy      |  "SUB" expr %prec UMINUS
61356341Scy            {  $$ = - $2; }
62356341Scy      |  LETTER
63356341Scy            {  $$ = regs[$1]; }
64356341Scy      |  number
65356341Scy      ;
66335640Shselasky
67356341Scynumber:  DIGIT
68335640Shselasky         {  $$ = $1; base = ($1==0) ? 8 : 10; }
69335640Shselasky      |  number DIGIT
70335640Shselasky         {  $$ = base * $1 + $2; }
71335640Shselasky      ;
72356341Scy
73%% /* start of programs */
74
75int
76main (void)
77{
78    while(!feof(stdin)) {
79	yyparse();
80    }
81    return 0;
82}
83
84static void
85yyerror(const char *s)
86{
87    fprintf(stderr, "%s\n", s);
88}
89
90int
91yylex(void) {
92	/* lexical analysis routine */
93	/* returns LETTER for a lower case letter, yylval = 0 through 25 */
94	/* return DIGIT for a digit, yylval = 0 through 9 */
95	/* all other characters are returned immediately */
96
97    int c;
98
99    while( (c=getchar()) == ' ' )   { /* skip blanks */ }
100
101    /* c is now nonblank */
102
103    if( islower( c )) {
104	yylval = c - 'a';
105	return ( LETTER );
106    }
107    if( isdigit( c )) {
108	yylval = c - '0';
109	return ( DIGIT );
110    }
111    return( c );
112}
113