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%token OCT1 '\177'
28%token HEX1 '\xff'
29%token HEX2 '\xFF'
30%token HEX3 '\x7f'
31%token STR1 "\x7f\177\\\n"
32%token STR2 "\x7f\
33\177\\\n"
34
35%token BELL '\a'
36%token BS   '\b'
37%token NL   '\n'
38%token LF   '\f'
39%token CR   '\r'
40%token TAB  '\t'
41%token VT   '\v'
42
43%union
44{
45    char *	cval;
46    int		ival;
47    double	dval;
48}
49
50%0 '@'
51%2 '~'
52%> '^'
53%< '#'
54
55%left '|'
56%left '&'
57%left '+' '-'
58%left '*' '/' '%'
59%left UMINUS   /* supplies precedence for unary minus */
60
61%% /* beginning of rules section */
62
63list  :  /* empty */
64      |  list stat '\n'
65      |  list error '\n'
66            {  yyerrok ; }
67      ;
68
69stat  :  expr
70            {  printf("%d\n",$<ival>1);}
71      |  LETTER '=' expr
72            {  regs[$<ival>1] = $<ival>3; }
73      ;
74
75expr  :  '(' expr ')'
76            {  $<ival>$ = $<ival>2; }
77      |  expr '+' expr
78            {  $<ival>$ = $<ival>1 + $<ival>3; }
79      |  expr '-' expr
80            {  $<ival>$ = $<ival>1 - $<ival>3; }
81      |  expr '*' expr
82            {  $<ival>$ = $<ival>1 * $<ival>3; }
83      |  expr '/' expr
84            {  $<ival>$ = $<ival>1 / $<ival>3; }
85      |  expr '%' expr
86            {  $<ival>$ = $<ival>1 % $<ival>3; }
87      |  expr '&' expr
88            {  $<ival>$ = $<ival>1 & $<ival>3; }
89      |  expr '|' expr
90            {  $<ival>$ = $<ival>1 | $<ival>3; }
91      |  '-' expr %prec UMINUS
92            {  $<ival>$ = - $<ival>2; }
93      |  LETTER
94            {  $<ival>$ = regs[$<ival>1]; }
95      |  number
96      ;
97
98number:  DIGIT
99         {  $<ival>$ = $<ival>1; (*base) = ($<ival>1==0) ? 8 : 10; }
100      |  number DIGIT
101         {  $<ival>$ = (*base) * $<ival>1 + $<ival>2; }
102      ;
103
104%% /* start of programs */
105
106#ifdef YYBYACC
107extern int YYLEX_DECL();
108#endif
109
110int
111main (void)
112{
113    int regs[26];
114    int base = 10;
115
116    while(!feof(stdin)) {
117	yyparse(regs, &base);
118    }
119    return 0;
120}
121
122#define UNUSED(x) ((void)(x))
123
124static void
125YYERROR_DECL()
126{
127    UNUSED(regs); /* %parse-param regs is not actually used here */
128    UNUSED(base); /* %parse-param base is not actually used here */
129    fprintf(stderr, "%s\n", s);
130}
131
132int
133YYLEX_DECL()
134{
135	/* lexical analysis routine */
136	/* returns LETTER for a lower case letter, yylval = 0 through 25 */
137	/* return DIGIT for a digit, yylval = 0 through 9 */
138	/* all other characters are returned immediately */
139
140    int c;
141
142    while( (c=getchar()) == ' ' )   { /* skip blanks */ }
143
144    /* c is now nonblank */
145
146    if( islower( c )) {
147	yylval->ival = (c - 'a');
148	return ( LETTER );
149    }
150    if( isdigit( c )) {
151	yylval->ival = (c - '0') % (*base);
152	return ( DIGIT );
153    }
154    return( c );
155}
156