xref: /netbsd-src/external/bsd/byacc/dist/test/calc_code_provides.y (revision 297954931ad0d67561c9ad372cf647561d24aabf)
1 /*	$NetBSD: calc_code_provides.y,v 1.1.1.1 2021/02/20 20:30:07 christos Exp $	*/
2 
3 %code provides { /* CODE-PROVIDES */ }
4 %code provides { /* CODE-PROVIDES2 */ }
5 
6 %{
7 # include <stdio.h>
8 # include <ctype.h>
9 
10 int regs[26];
11 int base;
12 
13 extern int yylex(void);
14 static void yyerror(const char *s);
15 
16 %}
17 
18 %start list
19 
20 %token DIGIT LETTER
21 
22 %left '|'
23 %left '&'
24 %left '+' '-'
25 %left '*' '/' '%'
26 %left UMINUS   /* supplies precedence for unary minus */
27 
28 %% /* beginning of rules section */
29 
30 list  :  /* empty */
31       |  list stat '\n'
32       |  list error '\n'
33             {  yyerrok ; }
34       ;
35 
36 stat  :  expr
37             {  printf("%d\n",$1);}
38       |  LETTER '=' expr
39             {  regs[$1] = $3; }
40       ;
41 
42 expr  :  '(' expr ')'
43             {  $$ = $2; }
44       |  expr '+' expr
45             {  $$ = $1 + $3; }
46       |  expr '-' expr
47             {  $$ = $1 - $3; }
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 %prec UMINUS
59             {  $$ = - $2; }
60       |  LETTER
61             {  $$ = regs[$1]; }
62       |  number
63       ;
64 
65 number:  DIGIT
66          {  $$ = $1; base = ($1==0) ? 8 : 10; }
67       |  number DIGIT
68          {  $$ = base * $1 + $2; }
69       ;
70 
71 %% /* start of programs */
72 
73 int
74 main (void)
75 {
76     while(!feof(stdin)) {
77 	yyparse();
78     }
79     return 0;
80 }
81 
82 static void
yyerror(const char * s)83 yyerror(const char *s)
84 {
85     fprintf(stderr, "%s\n", s);
86 }
87 
88 int
yylex(void)89 yylex(void)
90 {
91 	/* lexical analysis routine */
92 	/* returns LETTER for a lower case letter, yylval = 0 through 25 */
93 	/* return DIGIT for a digit, yylval = 0 through 9 */
94 	/* all other characters are returned immediately */
95 
96     int c;
97 
98     while( (c=getchar()) == ' ' )   { /* skip blanks */ }
99 
100     /* c is now nonblank */
101 
102     if( islower( c )) {
103 	yylval = c - 'a';
104 	return ( LETTER );
105     }
106     if( isdigit( c )) {
107 	yylval = c - '0';
108 	return ( DIGIT );
109     }
110     return( c );
111 }
112