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