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