xref: /freebsd/contrib/byacc/test/ok_syntax1.y (revision 2e3507c25e42292b45a5482e116d278f5515d04d)
1 %pure_parser
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 YYSTYPE int
14 #define YYLEX_PARAM base
15 #define YYLEX_DECL() yylex(YYSTYPE *yylval, int *YYLEX_PARAM)
16 #define YYERROR_DECL() yyerror(int regs[26], int *base, const char *s)
17 int YYLEX_DECL();
18 static void YYERROR_DECL();
19 #endif
20 
21 %}
22 
23 %start list
24 
25 %token DIGIT LETTER
26 
27 %token OCT1 '\177'
28 %token HEX1 '\xff'
29 %token HEX2 '\xFF'
30 %token HEX3 '\x7f'
31 %token STR1 "\x7f\177\\\n"
32 %token STR2 "\x7f\
33 \177\\\n"
34 
35 %token BELL '\a'
36 %token BS   '\b'
37 %token NL   '\n'
38 %token LF   '\f'
39 %token CR   '\r'
40 %token TAB  '\t'
41 %token VT   '\v'
42 
43 %union
44 {
45     char *	cval;
46     int		ival;
47     double	dval;
48 }
49 
50 %0 '@'
51 %2 '~'
52 %> '^'
53 %< '#'
54 
55 %left '|'
56 %left '&'
57 %left '+' '-'
58 %left '*' '/' '%'
59 %left UMINUS   /* supplies precedence for unary minus */
60 
61 %% /* beginning of rules section */
62 
63 list  :  /* empty */
64       |  list stat '\n'
65       |  list error '\n'
66             {  yyerrok ; }
67       ;
68 
69 stat  :  expr
70             {  printf("%d\n",$<ival>1);}
71       |  LETTER '=' expr
72             {  regs[$<ival>1] = $<ival>3; }
73       ;
74 
75 expr  :  '(' expr ')'
76             {  $<ival>$ = $<ival>2; }
77       |  expr '+' expr
78             {  $<ival>$ = $<ival>1 + $<ival>3; }
79       |  expr '-' expr
80             {  $<ival>$ = $<ival>1 - $<ival>3; }
81       |  expr '*' expr
82             {  $<ival>$ = $<ival>1 * $<ival>3; }
83       |  expr '/' expr
84             {  $<ival>$ = $<ival>1 / $<ival>3; }
85       |  expr '%' expr
86             {  $<ival>$ = $<ival>1 % $<ival>3; }
87       |  expr '&' expr
88             {  $<ival>$ = $<ival>1 & $<ival>3; }
89       |  expr '|' expr
90             {  $<ival>$ = $<ival>1 | $<ival>3; }
91       |  '-' expr %prec UMINUS
92             {  $<ival>$ = - $<ival>2; }
93       |  LETTER
94             {  $<ival>$ = regs[$<ival>1]; }
95       |  number
96       ;
97 
98 number:  DIGIT
99          {  $<ival>$ = $<ival>1; (*base) = ($<ival>1==0) ? 8 : 10; }
100       |  number DIGIT
101          {  $<ival>$ = (*base) * $<ival>1 + $<ival>2; }
102       ;
103 
104 %% /* start of programs */
105 
106 #ifdef YYBYACC
107 extern int YYLEX_DECL();
108 #endif
109 
110 int
111 main (void)
112 {
113     int regs[26];
114     int base = 10;
115 
116     while(!feof(stdin)) {
117 	yyparse(regs, &base);
118     }
119     return 0;
120 }
121 
122 #define UNUSED(x) ((void)(x))
123 
124 static void
125 YYERROR_DECL()
126 {
127     UNUSED(regs); /* %parse-param regs is not actually used here */
128     UNUSED(base); /* %parse-param base is not actually used here */
129     fprintf(stderr, "%s\n", s);
130 }
131 
132 int
133 YYLEX_DECL()
134 {
135 	/* lexical analysis routine */
136 	/* returns LETTER for a lower case letter, yylval = 0 through 25 */
137 	/* return DIGIT for a digit, yylval = 0 through 9 */
138 	/* all other characters are returned immediately */
139 
140     int c;
141 
142     while( (c=getchar()) == ' ' )   { /* skip blanks */ }
143 
144     /* c is now nonblank */
145 
146     if( islower( c )) {
147 	yylval->ival = (c - 'a');
148 	return ( LETTER );
149     }
150     if( isdigit( c )) {
151 	yylval->ival = (c - '0') % (*base);
152 	return ( DIGIT );
153     }
154     return( c );
155 }
156