1234949Sbapt%{
2234949Sbapt# include <stdio.h>
3234949Sbapt# include <ctype.h>
4234949Sbapt
5234949Sbaptint regs[26];
6234949Sbaptint base;
7234949Sbapt
8234949Sbapt#ifdef YYBISON
9234949Sbapt#define YYSTYPE int
10234949Sbapt#define YYLEX_PARAM &yylval
11234949Sbapt#define YYLEX_DECL() yylex(YYSTYPE *yylval)
12234949Sbapt#define YYERROR_DECL() yyerror(const char *s)
13234949Sbaptint YYLEX_DECL();
14234949Sbaptstatic void YYERROR_DECL();
15234949Sbapt#endif
16234949Sbapt
17234949Sbapt%}
18234949Sbapt
19234949Sbapt%start list
20234949Sbapt
21234949Sbapt%token DIGIT LETTER
22234949Sbapt
23234949Sbapt%left '|'
24234949Sbapt%left '&'
25234949Sbapt%left '+' '-'
26234949Sbapt%left '*' '/' '%'
27234949Sbapt%left UMINUS   /* supplies precedence for unary minus */
28234949Sbapt
29234949Sbapt%% /* beginning of rules section */
30234949Sbapt
31234949Sbaptlist  :  /* empty */
32234949Sbapt      |  list stat '\n'
33234949Sbapt      |  list error '\n'
34234949Sbapt            {  yyerrok ; }
35234949Sbapt      ;
36234949Sbapt
37234949Sbaptstat  :  expr
38234949Sbapt            {  printf("%d\n",$1);}
39234949Sbapt      |  LETTER '=' expr
40234949Sbapt            {  regs[$1] = $3; }
41234949Sbapt      ;
42234949Sbapt
43234949Sbaptexpr  :  '(' expr ')'
44234949Sbapt            {  $$ = $2; }
45234949Sbapt      |  expr '+' expr
46234949Sbapt            {  $$ = $1 + $3; }
47234949Sbapt      |  expr '-' expr
48234949Sbapt            {  $$ = $1 - $3; }
49234949Sbapt      |  expr '*' expr
50234949Sbapt            {  $$ = $1 * $3; }
51234949Sbapt      |  expr '/' expr
52234949Sbapt            {  $$ = $1 / $3; }
53234949Sbapt      |  expr '%' expr
54234949Sbapt            {  $$ = $1 % $3; }
55234949Sbapt      |  expr '&' expr
56234949Sbapt            {  $$ = $1 & $3; }
57234949Sbapt      |  expr '|' expr
58234949Sbapt            {  $$ = $1 | $3; }
59234949Sbapt      |  '-' expr %prec UMINUS
60234949Sbapt            {  $$ = - $2; }
61234949Sbapt      |  LETTER
62234949Sbapt            {  $$ = regs[$1]; }
63234949Sbapt      |  number
64234949Sbapt      ;
65234949Sbapt
66234949Sbaptnumber:  DIGIT
67234949Sbapt         {  $$ = $1; base = ($1==0) ? 8 : 10; }
68234949Sbapt      |  number DIGIT
69234949Sbapt         {  $$ = base * $1 + $2; }
70234949Sbapt      ;
71234949Sbapt
72234949Sbapt%% /* start of programs */
73234949Sbapt
74234949Sbapt#ifdef YYBYACC
75234949Sbaptstatic int YYLEX_DECL();
76234949Sbapt#endif
77234949Sbapt
78234949Sbaptint
79234949Sbaptmain (void)
80234949Sbapt{
81234949Sbapt    while(!feof(stdin)) {
82234949Sbapt	yyparse();
83234949Sbapt    }
84234949Sbapt    return 0;
85234949Sbapt}
86234949Sbapt
87234949Sbaptstatic void
88234949SbaptYYERROR_DECL()
89234949Sbapt{
90234949Sbapt    fprintf(stderr, "%s\n", s);
91234949Sbapt}
92234949Sbapt
93234949Sbaptint
94234949SbaptYYLEX_DECL()
95234949Sbapt{
96234949Sbapt	/* lexical analysis routine */
97234949Sbapt	/* returns LETTER for a lower case letter, yylval = 0 through 25 */
98234949Sbapt	/* return DIGIT for a digit, yylval = 0 through 9 */
99234949Sbapt	/* all other characters are returned immediately */
100234949Sbapt
101234949Sbapt    int c;
102234949Sbapt
103234949Sbapt    while( (c=getchar()) == ' ' )   { /* skip blanks */ }
104234949Sbapt
105234949Sbapt    /* c is now nonblank */
106234949Sbapt
107234949Sbapt    if( islower( c )) {
108234949Sbapt	*yylval = c - 'a';
109234949Sbapt	return ( LETTER );
110234949Sbapt    }
111234949Sbapt    if( isdigit( c )) {
112234949Sbapt	*yylval = c - '0';
113234949Sbapt	return ( DIGIT );
114234949Sbapt    }
115234949Sbapt    return( c );
116234949Sbapt}
117