1 /* otp.y: Grammar for OTP files.
2 
3 This file is part of Omega,
4 which is based on the web2c distribution of TeX.
5 
6 Copyright (c) 1994--2001 John Plaice and Yannis Haralambous
7 Copyright (C) 2005, 2006 Roozbeh Pournader
8 
9 Omega is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13 
14 Omega is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Omega; if not, write to the Free Software Foundation, Inc.,
21 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22 
23 */
24 
25 %{
26 #include "otp.h"
27 #include "routines.h"
28 #include "yystype.h"
29 int k, len;
30 
31 static void
yyerror(const char * msg)32 yyerror(const char *msg)
33 {
34 fprintf(stderr, "line %d: %s\n", line_number, msg);
35 }
36 %}
37 
38 %token NUMBER
39 %token ID
40 %token STRING
41 %token LEFTARROW
42 %token RIGHTARROW
43 %token INPUT
44 %token OUTPUT
45 %token ALIASES
46 %token STATES
47 %token TABLES
48 %token EXPRESSIONS
49 %token PUSH
50 %token POP
51 %token DIV
52 %token MOD
53 %token BEG
54 %token END
55 
56 %left '+' '-'
57 %left '*' DIV MOD
58 
59 %%
60 
61 File :
62 	Input
63 	Output
64 	Tables
65 	States
66 	Aliases
67 	Expressions
68     ;
69 
70 Input :
71 	/* Empty */
72 	{ input_bytes=2; }
73     |	INPUT NUMBER ';'
74 	{ input_bytes=$2.yint; }
75     ;
76 
77 Output :
78 	/* Empty */
79 	{ output_bytes=2; }
80     |	OUTPUT NUMBER ';'
81 	{ output_bytes=$2.yint; }
82     ;
83 
84 Tables :
85 	/* Empty */
86     |	TABLES MoreTables
87     ;
88 
89 MoreTables :
90 	OneTable
91     |   MoreTables OneTable
92     ;
93 
94 OneTable :
95 	ID '[' NUMBER ']'
96 	{ store_table($1.ystring, $3.yint); }
97 	'=' '{' Numbers '}' ';'
98     ;
99 
100 Numbers :
101 	/* Empty */
102     |	MoreNumbers
103     ;
104 
105 MoreNumbers :
106 	NUMBER
107 	{ add_to_table($1.yint); }
108     |   MoreNumbers ',' NUMBER
109 	{ add_to_table($3.yint); }
110     ;
111 
112 States :
113 	/* Empty */
114     |	STATES MoreStates ';'
115     ;
116 
117 MoreStates :
118 	ID
119 	{ store_state($1.ystring); }
120     |   MoreStates ',' ID
121 	{ store_state($3.ystring); }
122     ;
123 
124 Aliases :
125 	/* Empty */
126     |	ALIASES MoreAliases
127     ;
128 
129 MoreAliases :
130 	OneAlias
131     |	MoreAliases OneAlias
132     ;
133 
134 OneAlias :
135 	ID '=' OneCompleteLeft ';'
136 	{ store_alias($1.ystring, $3.yleft); }
137     ;
138 
139 OneCompleteLeft :
140 	STRING
141 	{ $$.yleft = StringLeft($1.ystring); }
142     |   OneLeft '<' NUMBER ',' NUMBER '>'
143 	{ $$.yleft = CompleteLeft($1.yleft, $3.yint, $5.yint); }
144     |	OneLeft '<' NUMBER ',' '>'
145 	{ $$.yleft = PlusLeft($1.yleft, $3.yint); }
146     |   OneLeft '<' NUMBER '>'
147 	{ $$.yleft = CompleteLeft($1.yleft, $3.yint, $3.yint); }
148     |	OneLeft
149 	{ $$.yleft = $1.yleft; }
150     ;
151 
152 OneLeft :
153 	NUMBER
154 	{ $$.yleft = SingleLeft($1.yint); }
155     |	NUMBER '-' NUMBER
156 	{ $$.yleft = DoubleLeft($1.yint, $3.yint); }
157     |   '.'
158 	{ $$.yleft = WildCard(); }
159     |   '^' '(' ChoiceLeft ')'
160 	{ $$.yleft = NotChoiceLeft($3.ylleft); }
161     |   '(' ChoiceLeft ')'
162 	{ $$.yleft = ChoiceLeft($2.ylleft); }
163     |	'{' ID '}'
164 	{ $$.yleft = lookup_alias($2.ystring); }
165     ;
166 
167 ChoiceLeft :
168 	OneLeft
169 	{ $$.ylleft = llist1($1.yleft); }
170     |	ChoiceLeft '|' OneLeft
171 	{ $$.ylleft = lappend1($1.ylleft, $3.yleft); }
172     ;
173 
174 Expressions :
175     	EXPRESSIONS MoreExpressions
176 	{
177 	  for(cur_state=0; cur_state<no_states; cur_state++) {
178 		  if ((states[cur_state].no_exprs)==0) {
179         	     out_int(OTP_LEFT_START, 0);
180 		  } else {
181         	     out_int(OTP_LEFT_RETURN, 0);
182                   }
183 		  out_int(OTP_RIGHT_CHAR, 1);
184 		  out_int(OTP_STOP, 0);
185 	  }
186 	}
187     ;
188 
189 MoreExpressions :
190 	OneExpr
191     |	MoreExpressions OneExpr
192     ;
193 
194 OneExpr :
195 	LeftState
196 	{ states[cur_state].no_exprs++; }
197 	TotalLeft
198 	{ out_left($3.ylleft); right_offset=0; }
199 	RIGHTARROW Right
200 	{ right_offset=OTP_PBACK_OFFSET; }
201 	PushBack RightState ';'
202 	{ fill_in_left(); }
203     ;
204 
205 PushBack :
206     	/* Empty */
207     |	LEFTARROW Right
208     ;
209 
210 LeftState :
211 	/* Empty */
212 	{ cur_state = 0; }
213     |   '<' ID '>'
214 	{ cur_state = lookup_state($2.ystring); }
215     ;
216 
217 TotalLeft :
218 	BegLeft Left EndLeft
219 	{ $$.ylleft = lappend($1.ylleft, lappend($2.ylleft, $3.ylleft)); }
220 |	BegLeft EndLeft
221 	{ $$.ylleft = lappend($1.ylleft, $2.ylleft); }
222     ;
223 
224 BegLeft :
225 	/* Empty */
226 	{ $$.ylleft = nil; }
227     |   BEG
228 	{ $$.ylleft = llist1(BeginningLeft()); }
229     ;
230 
231 EndLeft :
232 	/* Empty */
233 	{ $$.ylleft = nil; }
234     |   END
235 	{ $$.ylleft = llist1(EndLeft()); }
236     ;
237 
238 Left :
239 	OneCompleteLeft
240 	{ $$.ylleft = llist1($1.yleft); }
241     |	Left OneCompleteLeft
242 	{ $$.ylleft = lappend1($1.ylleft, $2.yleft); }
243     ;
244 
245 Right :
246 	/* Empty */
247     |	Right OneRight
248     ;
249 
250 OneRight :
251 	STRING
252 	{
253 	 len=strlen($1.ystring);
254 	 for (k=0; k<len; k++) {
255             out_right(OTP_RIGHT_NUM, ($1.ystring)[k]);
256          }
257 	}
258     |	NUMBER
259 	{ out_right(OTP_RIGHT_NUM, $1.yint); }
260     |	'\\' NUMBER
261 	{ out_right(OTP_RIGHT_CHAR, $2.yint); }
262     |	'\\' '$'
263 	{ out_right(OTP_RIGHT_LCHAR, 0); }
264     |   '\\' '(' '$' '-' NUMBER ')'
265 	{ out_right(OTP_RIGHT_LCHAR, $5.yint); }
266     |   '\\' '*'
267 	{
268 	 out_right(OTP_RIGHT_SOME, 0);
269 	 out_int(0,0);
270 	}
271     |   '\\' '(' '*' '+' NUMBER ')'
272 	{
273 	 out_right(OTP_RIGHT_SOME, $5.yint);
274 	 out_int(0, 0);
275 	}
276     |   '\\' '(' '*' '-' NUMBER ')'
277 	{
278 	 out_right(OTP_RIGHT_SOME, 0);
279 	 out_int(0, $5.yint);
280 	}
281     |   '\\' '(' '*' '+' NUMBER '-' NUMBER ')'
282 	{
283 	 out_right(OTP_RIGHT_SOME, $5.yint);
284 	 out_int(0, $7.yint);
285 	}
286     |	'#' OneRightExpr
287 	{ out_right(OTP_RIGHT_OUTPUT, 0); }
288     ;
289 
290 RestRightExpr :
291 	OneRightExpr
292     |	RestRightExpr '+' OneRightExpr
293 	{ out_int(OTP_ADD, 0); }
294     |	RestRightExpr '-' OneRightExpr
295 	{ out_int(OTP_SUB, 0); }
296     |	RestRightExpr '*' OneRightExpr
297 	{ out_int(OTP_MULT, 0); }
298     |	RestRightExpr DIV OneRightExpr
299 	{ out_int(OTP_DIV, 0); }
300     |	RestRightExpr MOD OneRightExpr
301 	{ out_int(OTP_MOD, 0); }
302     |	ID
303 	{ out_int(OTP_PUSH_NUM, lookup_table($1.ystring)); }
304 	'[' RestRightExpr ']'
305 	{ out_int(OTP_LOOKUP, 0); }
306     ;
307 
308 OneRightExpr :
309 	NUMBER
310 	{ out_int(OTP_PUSH_NUM, $1.yint); }
311     |	'\\' NUMBER
312 	{ out_int(OTP_PUSH_CHAR, $2.yint); }
313     |	'\\' '$'
314 	{ out_int(OTP_PUSH_LCHAR, 0); }
315     |   '\\' '(' '$' '-' NUMBER ')'
316 	{ out_int(OTP_PUSH_LCHAR, $5.yint); }
317     |	'(' RestRightExpr ')'
318     ;
319 
320 RightState :
321 	/* Empty */
322     |   '<' '>'
323 	{ out_int(OTP_STATE_CHANGE, 0); }
324     |   '<' ID '>'
325 	{ out_int(OTP_STATE_CHANGE, lookup_state($2.ystring)); }
326     |   '<' PUSH ID '>'
327 	{ out_int(OTP_STATE_PUSH, lookup_state($3.ystring)); }
328     |   '<' POP '>'
329 	{ out_int(OTP_STATE_POP, 0); }
330     ;
331 %%
332