1235723Sbapt%pure-parser
2235723Sbapt
3235723Sbapt%parse-param { int regs[26] }
4235723Sbapt%parse-param { int *base }
5235723Sbapt
6235723Sbapt%lex-param { int *base }
7235723Sbapt
8235723Sbapt%{
9235723Sbapt# include <stdio.h>
10235723Sbapt# include <ctype.h>
11235723Sbapt
12235723Sbapt#ifdef YYBISON
13235723Sbapt#define YYSTYPE int
14235723Sbapt#define YYLEX_PARAM base
15235723Sbapt#define YYLEX_DECL() yylex(YYSTYPE *yylval, int *YYLEX_PARAM)
16235723Sbapt#define YYERROR_DECL() yyerror(int regs[26], int *base, const char *s)
17235723Sbaptint YYLEX_DECL();
18235723Sbaptstatic void YYERROR_DECL();
19235723Sbapt#endif
20235723Sbapt
21235723Sbapt%}
22235723Sbapt
23235723Sbapt%start list
24235723Sbapt
25235723Sbapt%token DIGIT LETTER
26235723Sbapt
27235723Sbapt%left '|'
28235723Sbapt%left '&'
29235723Sbapt%left '+' '-'
30235723Sbapt%left '*' '/' '%'
31235723Sbapt%left UMINUS   /* supplies precedence for unary minus */
32235723Sbapt
33235723Sbapt%% /* beginning of rules section */
34235723Sbapt
35235723Sbaptlist  :  /* empty */
36235723Sbapt      |  list stat '\n'
37235723Sbapt      |  list error '\n'
38235723Sbapt            {  yyerrok ; }
39235723Sbapt      ;
40235723Sbapt
41235723Sbaptstat  :  expr
42235723Sbapt            {  printf("%d\n",$1);}
43235723Sbapt      |  LETTER '=' expr
44235723Sbapt            {  regs[$1] = $3; }
45235723Sbapt      ;
46235723Sbapt
47235723Sbaptexpr  :  '(' expr ')'
48235723Sbapt            {  $$ = $2; }
49235723Sbapt      |  expr '+' expr
50235723Sbapt            {  $$ = $1 + $3; }
51235723Sbapt      |  expr '-' expr
52235723Sbapt            {  $$ = $1 - $3; }
53235723Sbapt      |  expr '*' expr
54235723Sbapt            {  $$ = $1 * $3; }
55235723Sbapt      |  expr '/' expr
56235723Sbapt            {  $$ = $1 / $3; }
57235723Sbapt      |  expr '%' expr
58235723Sbapt            {  $$ = $1 % $3; }
59235723Sbapt      |  expr '&' expr
60235723Sbapt            {  $$ = $1 & $3; }
61235723Sbapt      |  expr '|' expr
62235723Sbapt            {  $$ = $1 | $3; }
63235723Sbapt      |  '-' expr %prec UMINUS
64235723Sbapt            {  $$ = - $2; }
65235723Sbapt      |  LETTER
66235723Sbapt            {  $$ = regs[$1]; }
67235723Sbapt      |  number
68235723Sbapt      ;
69235723Sbapt
70235723Sbaptnumber:  DIGIT
71235723Sbapt         {  $$ = $1; (*base) = ($1==0) ? 8 : 10; }
72235723Sbapt      |  number DIGIT
73235723Sbapt         {  $$ = (*base) * $1 + $2; }
74235723Sbapt      ;
75235723Sbapt
76235723Sbapt%% /* start of programs */
77235723Sbapt
78235723Sbapt#ifdef YYBYACC
79235723Sbaptextern int YYLEX_DECL();
80235723Sbapt#endif
81235723Sbapt
82235723Sbaptint
83235723Sbaptmain (void)
84235723Sbapt{
85235723Sbapt    int regs[26];
86235723Sbapt    int base = 10;
87235723Sbapt
88235723Sbapt    while(!feof(stdin)) {
89235723Sbapt	yyparse(regs, &base);
90235723Sbapt    }
91235723Sbapt    return 0;
92235723Sbapt}
93235723Sbapt
94235723Sbaptstatic void
95235723SbaptYYERROR_DECL()
96235723Sbapt{
97235723Sbapt    fprintf(stderr, "%s\n", s);
98235723Sbapt}
99235723Sbapt
100235723Sbaptint
101235723SbaptYYLEX_DECL()
102235723Sbapt{
103235723Sbapt	/* lexical analysis routine */
104235723Sbapt	/* returns LETTER for a lower case letter, yylval = 0 through 25 */
105235723Sbapt	/* return DIGIT for a digit, yylval = 0 through 9 */
106235723Sbapt	/* all other characters are returned immediately */
107235723Sbapt
108235723Sbapt    int c;
109235723Sbapt
110235723Sbapt    while( (c=getchar()) == ' ' )   { /* skip blanks */ }
111235723Sbapt
112235723Sbapt    /* c is now nonblank */
113235723Sbapt
114235723Sbapt    if( islower( c )) {
115235723Sbapt	*yylval = (c - 'a');
116235723Sbapt	return ( LETTER );
117235723Sbapt    }
118235723Sbapt    if( isdigit( c )) {
119235723Sbapt	*yylval = (c - '0') % (*base);
120235723Sbapt	return ( DIGIT );
121235723Sbapt    }
122235723Sbapt    return( c );
123235723Sbapt}
124