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