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