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%token OCT1 '\177'
28264790Sbapt%token HEX1 '\xff'
29264790Sbapt%token HEX2 '\xFF'
30264790Sbapt%token HEX3 '\x7f'
31264790Sbapt%token STR1 "\x7f\177\\\n"
32264790Sbapt%token STR2 "\x7f\
33264790Sbapt\177\\\n"
34264790Sbapt
35264790Sbapt%token BELL '\a'
36264790Sbapt%token BS   '\b'
37264790Sbapt%token NL   '\n'
38264790Sbapt%token LF   '\f'
39264790Sbapt%token CR   '\r'
40264790Sbapt%token TAB  '\t'
41264790Sbapt%token VT   '\v'
42264790Sbapt
43264790Sbapt%union
44264790Sbapt{
45264790Sbapt    char *	cval;
46264790Sbapt    int		ival;
47264790Sbapt    double	dval;
48264790Sbapt}
49264790Sbapt
50264790Sbapt%0 '@'
51264790Sbapt%2 '~'
52264790Sbapt%> '^'
53264790Sbapt%< '#'
54264790Sbapt
55264790Sbapt%left '|'
56264790Sbapt%left '&'
57264790Sbapt%left '+' '-'
58264790Sbapt%left '*' '/' '%'
59264790Sbapt%left UMINUS   /* supplies precedence for unary minus */
60264790Sbapt
61264790Sbapt%% /* beginning of rules section */
62264790Sbapt
63264790Sbaptlist  :  /* empty */
64264790Sbapt      |  list stat '\n'
65264790Sbapt      |  list error '\n'
66264790Sbapt            {  yyerrok ; }
67264790Sbapt      ;
68264790Sbapt
69264790Sbaptstat  :  expr
70264790Sbapt            {  printf("%d\n",$<ival>1);}
71264790Sbapt      |  LETTER '=' expr
72264790Sbapt            {  regs[$<ival>1] = $<ival>3; }
73264790Sbapt      ;
74264790Sbapt
75264790Sbaptexpr  :  '(' expr ')'
76264790Sbapt            {  $<ival>$ = $<ival>2; }
77264790Sbapt      |  expr '+' expr
78264790Sbapt            {  $<ival>$ = $<ival>1 + $<ival>3; }
79264790Sbapt      |  expr '-' expr
80264790Sbapt            {  $<ival>$ = $<ival>1 - $<ival>3; }
81264790Sbapt      |  expr '*' expr
82264790Sbapt            {  $<ival>$ = $<ival>1 * $<ival>3; }
83264790Sbapt      |  expr '/' expr
84264790Sbapt            {  $<ival>$ = $<ival>1 / $<ival>3; }
85264790Sbapt      |  expr '%' expr
86264790Sbapt            {  $<ival>$ = $<ival>1 % $<ival>3; }
87264790Sbapt      |  expr '&' expr
88264790Sbapt            {  $<ival>$ = $<ival>1 & $<ival>3; }
89264790Sbapt      |  expr '|' expr
90264790Sbapt            {  $<ival>$ = $<ival>1 | $<ival>3; }
91264790Sbapt      |  '-' expr %prec UMINUS
92264790Sbapt            {  $<ival>$ = - $<ival>2; }
93264790Sbapt      |  LETTER
94264790Sbapt            {  $<ival>$ = regs[$<ival>1]; }
95264790Sbapt      |  number
96264790Sbapt      ;
97264790Sbapt
98264790Sbaptnumber:  DIGIT
99264790Sbapt         {  $<ival>$ = $<ival>1; (*base) = ($<ival>1==0) ? 8 : 10; }
100264790Sbapt      |  number DIGIT
101264790Sbapt         {  $<ival>$ = (*base) * $<ival>1 + $<ival>2; }
102264790Sbapt      ;
103264790Sbapt
104264790Sbapt%% /* start of programs */
105264790Sbapt
106264790Sbapt#ifdef YYBYACC
107264790Sbaptextern int YYLEX_DECL();
108264790Sbapt#endif
109264790Sbapt
110264790Sbaptint
111264790Sbaptmain (void)
112264790Sbapt{
113264790Sbapt    int regs[26];
114264790Sbapt    int base = 10;
115264790Sbapt
116264790Sbapt    while(!feof(stdin)) {
117264790Sbapt	yyparse(regs, &base);
118264790Sbapt    }
119264790Sbapt    return 0;
120264790Sbapt}
121264790Sbapt
122264790Sbapt#define UNUSED(x) ((void)(x))
123264790Sbapt
124264790Sbaptstatic void
125264790SbaptYYERROR_DECL()
126264790Sbapt{
127264790Sbapt    UNUSED(regs); /* %parse-param regs is not actually used here */
128264790Sbapt    UNUSED(base); /* %parse-param base is not actually used here */
129264790Sbapt    fprintf(stderr, "%s\n", s);
130264790Sbapt}
131264790Sbapt
132264790Sbaptint
133264790SbaptYYLEX_DECL()
134264790Sbapt{
135264790Sbapt	/* lexical analysis routine */
136264790Sbapt	/* returns LETTER for a lower case letter, yylval = 0 through 25 */
137264790Sbapt	/* return DIGIT for a digit, yylval = 0 through 9 */
138264790Sbapt	/* all other characters are returned immediately */
139264790Sbapt
140264790Sbapt    int c;
141264790Sbapt
142264790Sbapt    while( (c=getchar()) == ' ' )   { /* skip blanks */ }
143264790Sbapt
144264790Sbapt    /* c is now nonblank */
145264790Sbapt
146264790Sbapt    if( islower( c )) {
147264790Sbapt	yylval->ival = (c - 'a');
148264790Sbapt	return ( LETTER );
149264790Sbapt    }
150264790Sbapt    if( isdigit( c )) {
151264790Sbapt	yylval->ival = (c - '0') % (*base);
152264790Sbapt	return ( DIGIT );
153264790Sbapt    }
154264790Sbapt    return( c );
155264790Sbapt}
156