1264790Sbapt%pure-parser
2264790Sbapt
3264790Sbapt%parse-param { int regs[26]
4264790Sbapt%parse-param { int *base
5264790Sbapt
6264790Sbapt%lex-param { int *base
7264790Sbapt
8264790Sbapt%{
9264790Sbapt# include <stdio.h>
10264790Sbapt# include <ctype.h>
11264790Sbapt
12264790Sbapt#ifdef YYBISON
13264790Sbapt#define YYSTYPE int
14264790Sbapt#define YYLEX_PARAM base
15264790Sbapt#define YYLEX_DECL() yylex(YYSTYPE *yylval, int *YYLEX_PARAM)
16264790Sbapt#define YYERROR_DECL() yyerror(int regs[26], int *base, const char *s)
17264790Sbaptint YYLEX_DECL();
18264790Sbaptstatic void YYERROR_DECL();
19264790Sbapt#endif
20264790Sbapt
21264790Sbapt%}
22264790Sbapt
23264790Sbapt%start list
24264790Sbapt
25264790Sbapt%token DIGIT LETTER
26264790Sbapt
27264790Sbapt%left '|'
28264790Sbapt%left '&'
29264790Sbapt%left '+' '-'
30264790Sbapt%left '*' '/' '%'
31264790Sbapt%left UMINUS   /* supplies precedence for unary minus */
32264790Sbapt
33264790Sbapt%% /* beginning of rules section */
34264790Sbapt
35264790Sbaptlist  :  /* empty */
36264790Sbapt      |  list stat '\n'
37264790Sbapt      |  list error '\n'
38264790Sbapt            {  yyerrok ; }
39264790Sbapt      ;
40264790Sbapt
41264790Sbaptstat  :  expr
42264790Sbapt            {  printf("%d\n",$1);}
43264790Sbapt      |  LETTER '=' expr
44264790Sbapt            {  regs[$1] = $3; }
45264790Sbapt      ;
46264790Sbapt
47264790Sbaptexpr  :  '(' expr ')'
48264790Sbapt            {  $$ = $2; }
49264790Sbapt      |  expr '+' expr
50264790Sbapt            {  $$ = $1 + $3; }
51264790Sbapt      |  expr '-' expr
52264790Sbapt            {  $$ = $1 - $3; }
53264790Sbapt      |  expr '*' expr
54264790Sbapt            {  $$ = $1 * $3; }
55264790Sbapt      |  expr '/' expr
56264790Sbapt            {  $$ = $1 / $3; }
57264790Sbapt      |  expr '%' expr
58264790Sbapt            {  $$ = $1 % $3; }
59264790Sbapt      |  expr '&' expr
60264790Sbapt            {  $$ = $1 & $3; }
61264790Sbapt      |  expr '|' expr
62264790Sbapt            {  $$ = $1 | $3; }
63264790Sbapt      |  '-' expr %prec UMINUS
64264790Sbapt            {  $$ = - $2; }
65264790Sbapt      |  LETTER
66264790Sbapt            {  $$ = regs[$1]; }
67264790Sbapt      |  number
68264790Sbapt      ;
69264790Sbapt
70264790Sbaptnumber:  DIGIT
71264790Sbapt         {  $$ = $1; (*base) = ($1==0) ? 8 : 10; }
72264790Sbapt      |  number DIGIT
73264790Sbapt         {  $$ = (*base) * $1 + $2; }
74264790Sbapt      ;
75264790Sbapt
76264790Sbapt%% /* start of programs */
77264790Sbapt
78264790Sbapt#ifdef YYBYACC
79264790Sbaptextern int YYLEX_DECL();
80264790Sbapt#endif
81264790Sbapt
82264790Sbaptint
83264790Sbaptmain (void)
84264790Sbapt{
85264790Sbapt    int regs[26];
86264790Sbapt    int base = 10;
87264790Sbapt
88264790Sbapt    while(!feof(stdin)) {
89264790Sbapt	yyparse(regs, &base);
90264790Sbapt    }
91264790Sbapt    return 0;
92264790Sbapt}
93264790Sbapt
94264790Sbapt#define UNUSED(x) ((void)(x))
95264790Sbapt
96264790Sbaptstatic void
97264790SbaptYYERROR_DECL()
98264790Sbapt{
99264790Sbapt    UNUSED(regs); /* %parse-param regs is not actually used here */
100264790Sbapt    UNUSED(base); /* %parse-param base is not actually used here */
101264790Sbapt    fprintf(stderr, "%s\n", s);
102264790Sbapt}
103264790Sbapt
104264790Sbaptint
105264790SbaptYYLEX_DECL()
106264790Sbapt{
107264790Sbapt	/* lexical analysis routine */
108264790Sbapt	/* returns LETTER for a lower case letter, yylval = 0 through 25 */
109264790Sbapt	/* return DIGIT for a digit, yylval = 0 through 9 */
110264790Sbapt	/* all other characters are returned immediately */
111264790Sbapt
112264790Sbapt    int c;
113264790Sbapt
114264790Sbapt    while( (c=getchar()) == ' ' )   { /* skip blanks */ }
115264790Sbapt
116264790Sbapt    /* c is now nonblank */
117264790Sbapt
118264790Sbapt    if( islower( c )) {
119264790Sbapt	*yylval = (c - 'a');
120264790Sbapt	return ( LETTER );
121264790Sbapt    }
122264790Sbapt    if( isdigit( c )) {
123264790Sbapt	*yylval = (c - '0') % (*base);
124264790Sbapt	return ( DIGIT );
125264790Sbapt    }
126264790Sbapt    return( c );
127264790Sbapt}
128