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