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