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