Release coccinelle-0.2.4
[bpt/coccinelle.git] / parsing_cocci / parser_cocci.mly
1 /*
2 * Copyright 2010, INRIA, University of Copenhagen
3 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
4 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
5 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
6 * This file is part of Coccinelle.
7 *
8 * Coccinelle is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, according to version 2 of the License.
11 *
12 * Coccinelle is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * The authors reserve the right to distribute this or future versions of
21 * Coccinelle under other licenses.
22 */
23
24
25 /*
26 * Copyright 2010, INRIA, University of Copenhagen
27 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
28 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
29 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
30 * This file is part of Coccinelle.
31 *
32 * Coccinelle is free software: you can redistribute it and/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation, according to version 2 of the License.
35 *
36 * Coccinelle is distributed in the hope that it will be useful,
37 * but WITHOUT ANY WARRANTY; without even the implied warranty of
38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 * GNU General Public License for more details.
40 *
41 * You should have received a copy of the GNU General Public License
42 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
43 *
44 * The authors reserve the right to distribute this or future versions of
45 * Coccinelle under other licenses.
46 */
47
48
49 %{
50
51 (* Not clear how to allow function declarations to specify a return type
52 and how to allow both to be specified as static, because they are in
53 different rules. The rules seem to have to be combined, which would allow
54 functions to be declared as local variables *)
55
56 (* Not clear how to let a function have a parameter of type void. At the
57 moment, void is allowed to be the type of a variable, which is wrong, and a
58 parameter needs both a type and an identifier *)
59
60 module Ast0 = Ast0_cocci
61 module Ast = Ast_cocci
62
63 (*let warning s v =
64 if !Flag.verbose_parsing
65 then Common.warning s v
66 else v*)
67
68 let make_info line logical_line =
69 { Ast.line = line; Ast.logical_line = logical_line }
70
71 let clt2info (_,line,logical_line) = make_info line logical_line
72
73 let clt2mcode str = function
74 (Data.MINUS,line,lline) ->
75 (str,Ast0.NONE,
76 (Ast.MINUS({Ast.line=line;Ast.logical_line=lline},ref[])))
77 | (Data.OPTMINUS,line,lline) ->
78 (str,Ast0.OPT,
79 (Ast.MINUS({Ast.line=line;Ast.logical_line=lline},ref[])))
80 | (Data.UNIQUEMINUS,line,lline) ->
81 (str,Ast0.UNIQUE,
82 (Ast.MINUS({Ast.line=line;Ast.logical_line=lline},ref[])))
83 | (Data.MULTIMINUS,line,lline) ->
84 (str,Ast0.MULTI,
85 (Ast.MINUS({Ast.line=line;Ast.logical_line=lline},ref[])))
86 | (Data.PLUS,line,lline) ->
87 (str,Ast0.NONE,Ast.PLUS({Ast.line=line;Ast.logical_line=lline}))
88 | (Data.CONTEXT,line,lline) ->
89 (str,Ast0.NONE,
90 Ast.CONTEXT({Ast.line=line;Ast.logical_line=lline},ref Ast.NOTHING))
91 | (Data.OPT,line,lline) ->
92 (str,Ast0.OPT,
93 Ast.CONTEXT({Ast.line=line;Ast.logical_line=lline},ref Ast.NOTHING))
94 | (Data.UNIQUE,line,lline) ->
95 (str,Ast0.UNIQUE,
96 Ast.CONTEXT({Ast.line=line;Ast.logical_line=lline},ref Ast.NOTHING))
97 | (Data.MULTI,line,lline) ->
98 (str,Ast0.MULTI,
99 Ast.CONTEXT({Ast.line=line;Ast.logical_line=lline},ref Ast.NOTHING))
100
101 let id2name (name, clt) = name
102 let id2clt (name, clt) = clt
103 let id2info (name, clt) = clt2info clt
104 let id2mcode (name, clt) = clt2mcode name clt
105
106 let arith_op ast_op left op right =
107 Ast0.Binary(left, clt2mcode (Ast.Arith ast_op) op, right)
108
109 let logic_op ast_op left op right =
110 Ast0.Binary(left, clt2mcode (Ast.Logical ast_op) op, right)
111
112 let top_dots l =
113 if List.exists (function Ast0.Circles(_) -> true | _ -> false) l
114 then Ast0.CIRCLES(l)
115 else if List.exists (function Ast0.Stars(_) -> true | _ -> false) l
116 then Ast0.STARS(l)
117 else Ast0.DOTS(l)
118
119 %}
120
121
122 %token EOF
123
124 %token TIdentifier TExpression TStatement TFunction TLocal TType TParameter
125 %token TWhy0 TPlus0 TBang0 Tlist TFresh TConstant TError TWords
126
127 %token<Data.line_type * int * int> Tchar Tshort Tint Tdouble Tfloat Tlong Tvoid
128 %token<Data.line_type * int * int> Tstruct Tunion
129 %token<Data.line_type * int * int> Tunsigned Tsigned
130
131 %token<Data.line_type * int * int> Tstatic Tconst Tvolatile
132
133 %token <Data.line_type * int * int> TIf TElse TWhile TFor TDo TReturn
134 %token <string * (Data.line_type * int * int)> TIdent TFunName TMetaFunName
135 %token <string * (Data.line_type * int * int)> TMetaId TMetaType TMetaErr
136 %token <string * (Data.line_type * int * int)> TMetaParam TMetaParamList
137 %token <string * (Data.line_type * int * int)> TMetaStm TMetaStmList TMetaFunc
138 %token <string * (Data.line_type * int * int)> TMetaLocalFunc TMetaExpList
139 %token <string * Ast0_cocci.fullType list option * (Data.line_type*int*int)>
140 TMetaExp TMetaConst
141 %token TArobArob
142
143 %token <Data.line_type * int * int> TEllipsis TOEllipsis TCEllipsis
144 %token <Data.line_type * int * int> TWhen
145 %token TLineEnd
146 %token <Data.line_type * int * int> TCircles TOCircles TCCircles
147 %token <Data.line_type * int * int> TStars TOStars TCStars
148
149 %token <Data.line_type * int * int> TWhy TDotDot TBang TOPar TOPar0 TMid
150 %token <Data.line_type * int * int> TMid0 TCPar TCPar0
151
152 %token <string * (Data.line_type * int * int)> TInclude TMinusFile TPlusFile
153
154 %token <Data.line_type * int * int> TInc TDec
155
156 %token <string * (Data.line_type * int * int)> TString TChar TFloat TInt
157
158 %token <Data.line_type * int * int> TOrLog
159 %token <Data.line_type * int * int> TAndLog
160 %token <Data.line_type * int * int> TOr
161 %token <Data.line_type * int * int> TXor
162 %token <Data.line_type * int * int> TAnd
163 %token <Data.line_type * int * int> TEqEq TNotEq
164 %token <Data.line_type * int * int> TInf TSup TInfEq TSupEq
165 %token <Data.line_type * int * int> TShl TShr
166 %token <Data.line_type * int * int> TPlus TMinus
167 %token <Data.line_type * int * int> TMul TDiv TMod
168
169 %token <Data.line_type * int * int> TOBrace TCBrace
170 %token <Data.line_type * int * int> TOCro TCCro
171
172 %token <Data.line_type * int * int> TPtrOp
173
174 %token <Data.line_type * int * int> TEq TDot TComma TPtVirg
175 %token <Ast_cocci.assignOp * (Data.line_type * int * int)> TAssign
176
177 /* operator precedence */
178 %nonassoc TIf
179 %nonassoc TElse
180
181 %left TOrLog
182 %left TAndLog
183 %left TOr
184 %left TXor
185 %left TAnd
186 %left TEqEq TNotEq
187 %left TInf TSup TInfEq TSupEq
188 %left TShl TShr
189 %left TPlus TMinus
190 %left TMul TDiv TMod
191
192 %start main
193 %type <Ast0_cocci.rule> main
194
195 %start meta_main
196 %type <Ast_cocci.metavar list> meta_main
197
198
199
200 %%
201
202 main: body EOF { $1 } | body TArobArob { $1 }
203 meta_main: meta_var_list_opt TArobArob { $1 }
204
205 /*****************************************************************************
206 *
207 *
208 *****************************************************************************/
209
210 meta_var:
211 arity TIdentifier pure_ident_or_meta_ident_list TPtVirg
212 { List.map
213 (function name ->
214 !Data.add_id_meta name;
215 Ast.MetaIdDecl($1,name))
216 $3 }
217 | arity TFresh TIdentifier pure_ident_or_meta_ident_list TPtVirg
218 { List.map
219 (function name ->
220 !Data.add_id_meta name;
221 Ast.MetaFreshIdDecl($1,name))
222 $4 }
223 | arity TType pure_ident_or_meta_ident_list TPtVirg
224 { List.map
225 (function name ->
226 !Data.add_type_meta name;
227 Ast.MetaTypeDecl($1,name))
228 $3 }
229 | arity TParameter pure_ident_or_meta_ident_list TPtVirg
230 { List.map
231 (function name ->
232 !Data.add_param_meta name;
233 Ast.MetaParamDecl($1,name))
234 $3 }
235 | arity TParameter Tlist pure_ident_or_meta_ident_list TPtVirg
236 { List.map
237 (function name ->
238 !Data.add_paramlist_meta name;
239 Ast.MetaParamListDecl($1,name))
240 $4 }
241 | arity TError pure_ident_or_meta_ident_list TPtVirg
242 { List.map
243 (function name ->
244 !Data.add_err_meta name;
245 Ast.MetaErrDecl($1,name))
246 $3 }
247 | arity TExpression pure_ident_or_meta_ident_list TPtVirg
248 { List.map
249 (function name ->
250 !Data.add_exp_meta None name;
251 Ast.MetaExpDecl($1,name))
252 $3 }
253 | arity TExpression Tlist pure_ident_or_meta_ident_list TPtVirg
254 { List.map
255 (function name ->
256 !Data.add_explist_meta name;
257 Ast.MetaExpListDecl($1,name))
258 $4 }
259 | arity TStatement pure_ident_or_meta_ident_list TPtVirg
260 { List.map
261 (function name ->
262 !Data.add_stm_meta name;
263 Ast.MetaStmDecl($1,name))
264 $3 }
265 | arity TStatement Tlist pure_ident_or_meta_ident_list TPtVirg
266 { List.map
267 (function name ->
268 !Data.add_stmlist_meta name;
269 Ast.MetaStmListDecl($1,name))
270 $4 }
271 | arity TFunction pure_ident_or_meta_ident_list TPtVirg
272 { List.map
273 (function name ->
274 !Data.add_func_meta name;
275 Ast.MetaFuncDecl($1,name))
276 $3 }
277 | arity TLocal TFunction pure_ident_or_meta_ident_list TPtVirg
278 { List.map
279 (function name ->
280 !Data.add_local_func_meta name;
281 Ast.MetaLocalFuncDecl($1,name))
282 $4 }
283 | arity meta_exp_type pure_ident_or_meta_ident_list TPtVirg
284 { List.map
285 (function name ->
286 !Data.add_exp_meta (Some $2) name;
287 Ast.MetaExpDecl($1,name))
288 $3 }
289 | arity TConstant meta_exp_type pure_ident_or_meta_ident_list TPtVirg
290 { List.map
291 (function name ->
292 !Data.add_const_meta (Some $3) name;
293 Ast.MetaConstDecl($1,name))
294 $4 }
295 | arity TConstant pure_ident_or_meta_ident_list TPtVirg
296 { List.map
297 (function name ->
298 !Data.add_const_meta None name;
299 Ast.MetaConstDecl($1,name))
300 $3 }
301
302 meta_exp_type:
303 ctype { [$1] }
304 | TOBrace ctype_list TCBrace { $2 }
305
306 arity: TBang0 { Ast.UNIQUE }
307 | TWhy0 { Ast.OPT }
308 | TPlus0 { Ast.MULTI }
309 | /* empty */ { Ast.NONE }
310
311 ctype: Tvoid
312 { Ast0.BaseType(clt2mcode Ast.VoidType $1, None) }
313 | ctype_qualif Tchar
314 { Ast0.BaseType(clt2mcode Ast.CharType $2, $1) }
315 | ctype_qualif Tshort
316 { Ast0.BaseType(clt2mcode Ast.ShortType $2, $1) }
317 | ctype_qualif Tint
318 { Ast0.BaseType(clt2mcode Ast.IntType $2, $1) }
319 | Tdouble
320 { Ast0.BaseType(clt2mcode Ast.DoubleType $1, None) }
321 | Tfloat
322 { Ast0.BaseType(clt2mcode Ast.FloatType $1, None) }
323 | ctype_qualif Tlong
324 { Ast0.BaseType(clt2mcode Ast.LongType $2, $1) }
325 | Tstruct pure_ident
326 { Ast0.StructUnionName(id2mcode $2,clt2mcode Ast.Struct $1) }
327 | Tunion pure_ident
328 { Ast0.StructUnionName(id2mcode $2,clt2mcode Ast.Union $1) }
329 | ctype TMul
330 { Ast0.Pointer($1,clt2mcode "*" $2) }
331 | TMetaType
332 { let (nm,clt) = $1 in Ast0.MetaType(clt2mcode nm clt) }
333
334 ctype_qualif:
335 Tunsigned
336 { Some (clt2mcode Ast.Unsigned $1) }
337 | Tsigned
338 { Some (clt2mcode Ast.Signed $1) }
339 | /* empty */ { None }
340
341 param_ctype:
342 Tvoid
343 { Ast0.BaseType(clt2mcode Ast.VoidType $1, None) }
344 | ctype_qualif Tchar
345 { Ast0.BaseType(clt2mcode Ast.CharType $2, $1) }
346 | ctype_qualif Tshort
347 { Ast0.BaseType(clt2mcode Ast.ShortType $2, $1) }
348 | ctype_qualif Tint
349 { Ast0.BaseType(clt2mcode Ast.IntType $2, $1) }
350 | Tdouble
351 { Ast0.BaseType(clt2mcode Ast.DoubleType $1, None) }
352 | Tfloat
353 { Ast0.BaseType(clt2mcode Ast.FloatType $1, None) }
354 | ctype_qualif Tlong
355 { Ast0.BaseType(clt2mcode Ast.LongType $2, $1) }
356 | Tstruct pure_ident
357 { Ast0.StructUnionName(id2mcode $2,clt2mcode Ast.Struct $1) }
358 | Tunion pure_ident
359 { Ast0.StructUnionName(id2mcode $2,clt2mcode Ast.Union $1) }
360 | pure_ident { Ast0.TypeName(id2mcode $1) }
361 | param_ctype TMul { Ast0.Pointer($1,clt2mcode "*" $2) }
362 | TMetaType
363 { let (nm,clt) = $1 in Ast0.MetaType(clt2mcode nm clt) }
364
365 /*****************************************************************************/
366
367 /* have to inline everything to avoid conflicts? switch to proper
368 declarations, statements, and expressions for the subterms */
369
370 body: function_decl_statement_or_expression { Top_level.top_level $1 }
371 | /* empty */ { [] }
372
373 /*****************************************************************************/
374
375 fundecl:
376 storage TFunName TOPar decl_list TCPar
377 TOBrace pre_post_decl_statement_and_expression_opt TCBrace
378 { Ast0.FunDecl($1, Ast0.Id(id2mcode $2), clt2mcode "(" $3, $4,
379 clt2mcode ")" $5, clt2mcode "{" $6, $7,
380 clt2mcode "}" $8) }
381 | storage TMetaFunName TOPar decl_list TCPar
382 TOBrace pre_post_decl_statement_and_expression_opt TCBrace
383 { Ast0.FunDecl($1, Ast0.MetaFunc(id2mcode $2), clt2mcode "(" $3, $4,
384 clt2mcode ")" $5, clt2mcode "{" $6, $7,
385 clt2mcode "}" $8) }
386
387 storage: Tstatic { Some (clt2mcode Ast.Static $1) }
388 | /* empty */ { None }
389
390 decl: decl_qualif param_ctype ident
391 { Ast0.Param($3, $1, $2) }
392 | TMetaParam
393 { let (nm,clt) = $1 in Ast0.MetaParam(clt2mcode nm clt) }
394
395 decl_qualif:
396 Tconst { Some (clt2mcode Ast.Const $1) }
397 | Tvolatile { Some (clt2mcode Ast.Volatile $1) }
398 | /* empty */ { None }
399
400 /*****************************************************************************/
401
402 statement:
403 TMetaStm
404 { let (nm,clt) = $1 in Ast0.MetaStmt(clt2mcode nm clt) }
405 | expr TPtVirg
406 { Ast0.ExprStatement ($1, clt2mcode ";" $2) }
407 | TIf TOPar eexpr TCPar single_statement %prec TIf
408 { Ast0.IfThen(clt2mcode "if" $1,
409 clt2mcode "(" $2,$3,clt2mcode ")" $4,$5) }
410 | TIf TOPar eexpr TCPar single_statement TElse single_statement
411 { Ast0.IfThenElse(clt2mcode "if" $1,
412 clt2mcode "(" $2,$3,clt2mcode ")" $4,$5,
413 clt2mcode "else" $6,$7) }
414 | TFor TOPar eexpr_opt TPtVirg eexpr_opt TPtVirg eexpr_opt TCPar
415 single_statement
416 { Ast0.For(clt2mcode "for" $1,clt2mcode "(" $2,$3,
417 clt2mcode ";" $4,$5,clt2mcode ";" $6,$7,clt2mcode ")" $8,$9) }
418 | TWhile TOPar eexpr TCPar single_statement
419 { Ast0.While(clt2mcode "while" $1,
420 clt2mcode "(" $2,$3,clt2mcode ")" $4,$5) }
421 | TDo single_statement TWhile TOPar eexpr TCPar TPtVirg
422 { Ast0.Do(clt2mcode "do" $1,$2,clt2mcode "while" $3,
423 clt2mcode "(" $4,$5,clt2mcode ")" $6, clt2mcode ";" $7) }
424 | TReturn eexpr TPtVirg
425 { Ast0.ReturnExpr(clt2mcode "return" $1,$2,clt2mcode ";" $3) }
426 | TReturn TPtVirg
427 { Ast0.Return(clt2mcode "return" $1,clt2mcode ";" $2) }
428 | TOBrace pre_post_decl_statement_and_expression_opt TCBrace
429 { Ast0.Seq(clt2mcode "{" $1,$2,clt2mcode "}" $3) }
430 | TOEllipsis decl_statement_or_expression_dots TCEllipsis
431 { Ast0.Nest(Ast0.DOTS($2)) }
432 | TOCircles decl_statement_or_expression_circles TCCircles
433 { Ast0.Nest(Ast0.CIRCLES($2)) }
434 | TOStars decl_statement_or_expression_stars TCStars
435 { Ast0.Nest(Ast0.STARS($2)) }
436
437 /* In the following, an identifier as a type is not fully supported. Indeed,
438 the language is ambiguous: what is foo * bar; */
439 decl_var: ctype d_ident_list TPtVirg
440 { (List.map
441 (function (id,fn) -> Ast0.UnInit(fn $1,id,clt2mcode ";" $3))
442 $2) }
443 | ctype d_ident TEq eexpr TPtVirg
444 { let (id,fn) = $2 in
445 [Ast0.Init(fn $1,id,clt2mcode "=" $3,$4,clt2mcode ";" $5)] }
446 | pure_ident d_ident TPtVirg
447 { let (id,fn) = $2 in
448 [Ast0.UnInit(fn (Ast0.TypeName(id2mcode $1)),id,clt2mcode ";" $3)] }
449 | pure_ident d_ident TEq eexpr TPtVirg
450 { let (id,fn) = $2 in
451 [Ast0.Init(fn(Ast0.TypeName(id2mcode $1)),id,
452 clt2mcode "=" $3,$4,clt2mcode ";" $5)] }
453
454 d_ident:
455 ident
456 { ($1,function x -> x) }
457 | ident TOCro eexpr_opt TCCro
458 { ($1,function x -> Ast0.Array(x,clt2mcode "[" $2,$3,clt2mcode "]" $4)) }
459
460 /* a statement on its own */
461 single_statement:
462 statement { $1 }
463 | TOPar0 statement_mid TCPar0
464 { Ast0.Disj($2) }
465
466 /* a statement that is part of a list */
467 decl_statement:
468 TMetaStmList
469 { let (nm,clt) = $1 in [Ast0.MetaStmt(clt2mcode nm clt)] }
470 | decl_var
471 { List.map (function x -> Ast0.Decl(x)) $1 }
472 | statement { [$1] }
473 | TOPar0 pre_post_decl_statement_and_expression_opt_mid TCPar0
474 { if List.for_all (function Ast0.DOTS([]) -> true | _ -> false) $2
475 then []
476 else [Ast0.Disj($2)] }
477
478 /*****************************************************************************/
479
480
481 /*****************************************************************************/
482 /* The following cannot contain <... ...> at the top level. This can only
483 be allowed as an expression when the expression is delimited on both sides
484 by expression-specific markers. In that case, the rule eexpr is used, which
485 allows <... ...> anywhere. Hopefully, this will not be too much of a problem
486 in practice. */
487
488 expr: assign_expr { $1 }
489
490 assign_expr:
491 cond_expr { $1 }
492 | unary_expr TAssign assign_expr
493 { let (op,clt) = $2 in Ast0.Assignment($1,clt2mcode op clt,$3) }
494 | unary_expr TEq assign_expr
495 { Ast0.Assignment($1,clt2mcode Ast.SimpleAssign $2,$3) }
496
497 cond_expr: arith_expr { $1 }
498 | arith_expr TWhy eexpr_opt TDotDot cond_expr
499 { Ast0.CondExpr ($1, clt2mcode "?" $2, $3, clt2mcode "?" $4, $5) }
500
501 arith_expr: cast_expr { $1 }
502 | arith_expr TMul arith_expr { arith_op Ast.Mul $1 $2 $3 }
503 | arith_expr TDiv arith_expr { arith_op Ast.Div $1 $2 $3 }
504 | arith_expr TMod arith_expr { arith_op Ast.Mod $1 $2 $3 }
505 | arith_expr TPlus arith_expr { arith_op Ast.Plus $1 $2 $3 }
506 | arith_expr TMinus arith_expr { arith_op Ast.Minus $1 $2 $3 }
507 | arith_expr TShl arith_expr { arith_op Ast.DecLeft $1 $2 $3 }
508 | arith_expr TShr arith_expr { arith_op Ast.DecRight $1 $2 $3 }
509 | arith_expr TInf arith_expr { logic_op Ast.Inf $1 $2 $3 }
510 | arith_expr TSup arith_expr { logic_op Ast.Sup $1 $2 $3 }
511 | arith_expr TInfEq arith_expr { logic_op Ast.InfEq $1 $2 $3 }
512 | arith_expr TSupEq arith_expr { logic_op Ast.SupEq $1 $2 $3 }
513 | arith_expr TEqEq arith_expr { logic_op Ast.Eq $1 $2 $3 }
514 | arith_expr TNotEq arith_expr { logic_op Ast.NotEq $1 $2 $3 }
515 | arith_expr TAnd arith_expr { arith_op Ast.And $1 $2 $3 }
516 | arith_expr TOr arith_expr { arith_op Ast.Or $1 $2 $3 }
517 | arith_expr TXor arith_expr { arith_op Ast.Xor $1 $2 $3 }
518 | arith_expr TAndLog arith_expr { logic_op Ast.AndLog $1 $2 $3 }
519 | arith_expr TOrLog arith_expr { logic_op Ast.OrLog $1 $2 $3 }
520
521 cast_expr: unary_expr { $1 }
522 | TOPar ctype TCPar cast_expr
523 { Ast0.Cast (clt2mcode "(" $1, $2, clt2mcode ")" $3, $4) }
524
525 unary_expr: postfix_expr { $1 }
526 | TInc unary_expr
527 { Ast0.Infix ($2, clt2mcode Ast.Inc $1) }
528 | TDec unary_expr
529 { Ast0.Infix ($2, clt2mcode Ast.Dec $1) }
530 | unary_op unary_expr
531 { let mcode = $1 in Ast0.Unary($2, mcode) }
532
533 unary_op: TAnd { clt2mcode Ast.GetRef $1 }
534 | TMul { clt2mcode Ast.DeRef $1 }
535 | TPlus { clt2mcode Ast.UnPlus $1 }
536 | TMinus { clt2mcode Ast.UnMinus $1 }
537 | TBang { clt2mcode Ast.Not $1 }
538
539 postfix_expr: primary_expr { $1 }
540 | postfix_expr TOCro eexpr TCCro
541 { Ast0.ArrayAccess ($1,clt2mcode "[" $2,$3,clt2mcode "]" $4) }
542 | postfix_expr TDot ident
543 { Ast0.RecordAccess($1, clt2mcode "." $2, $3) }
544 | postfix_expr TPtrOp ident
545 { Ast0.RecordPtAccess($1, clt2mcode "->" $2, $3) }
546 | postfix_expr TInc
547 { Ast0.Postfix ($1, clt2mcode Ast.Inc $2) }
548 | postfix_expr TDec
549 { Ast0.Postfix ($1, clt2mcode Ast.Dec $2) }
550 | postfix_expr TOPar eexpr_list_opt TCPar
551 { Ast0.FunCall($1,clt2mcode "(" $2,$3,clt2mcode ")" $4) }
552
553 primary_expr: ident { Ast0.Ident($1) }
554 | TInt
555 { let (x,clt) = $1 in
556 Ast0.Constant (clt2mcode (Ast.Int x) clt) }
557 | TFloat
558 { let (x,clt) = $1 in
559 Ast0.Constant (clt2mcode (Ast.Float x) clt) }
560 | TString
561 { let (x,clt) = $1 in
562 Ast0.Constant (clt2mcode (Ast.String x) clt) }
563 | TChar
564 { let (x,clt) = $1 in
565 Ast0.Constant (clt2mcode (Ast.Char x) clt) }
566 | TMetaConst
567 { let (nm,ty,clt) = $1 in Ast0.MetaConst(clt2mcode nm clt,ty) }
568 | TMetaErr
569 { let (nm,clt) = $1 in Ast0.MetaErr(clt2mcode nm clt) }
570 | TMetaExp
571 { let (nm,ty,clt) = $1 in Ast0.MetaExpr(clt2mcode nm clt,ty) }
572 | TOPar eexpr TCPar
573 { Ast0.Paren(clt2mcode "(" $1,$2,clt2mcode ")" $3) }
574 | TOPar0 expr_mid TCPar0 { Ast0.DisjExpr($2) }
575
576 /*****************************************************************************/
577
578 eexpr: eassign_expr { $1 }
579
580 eassign_expr: econd_expr { $1 }
581 | eunary_expr TAssign eassign_expr
582 { let (op,clt) = $2 in
583 Ast0.Assignment($1,clt2mcode op clt,$3) }
584 | eunary_expr TEq eassign_expr
585 { Ast0.Assignment($1,clt2mcode Ast.SimpleAssign $2,$3) }
586
587 econd_expr: earith_expr { $1 }
588 | earith_expr TWhy eexpr_opt TDotDot econd_expr
589 { Ast0.CondExpr ($1, clt2mcode "?" $2, $3, clt2mcode "?" $4, $5) }
590
591 earith_expr: ecast_expr { $1 }
592 | earith_expr TMul earith_expr { arith_op Ast.Mul $1 $2 $3 }
593 | earith_expr TDiv earith_expr { arith_op Ast.Div $1 $2 $3 }
594 | earith_expr TMod earith_expr { arith_op Ast.Mod $1 $2 $3 }
595 | earith_expr TPlus earith_expr { arith_op Ast.Plus $1 $2 $3 }
596 | earith_expr TMinus earith_expr { arith_op Ast.Minus $1 $2 $3 }
597 | earith_expr TShl earith_expr { arith_op Ast.DecLeft $1 $2 $3 }
598 | earith_expr TShr earith_expr { arith_op Ast.DecRight $1 $2 $3 }
599 | earith_expr TInf earith_expr { logic_op Ast.Inf $1 $2 $3 }
600 | earith_expr TSup earith_expr { logic_op Ast.Sup $1 $2 $3 }
601 | earith_expr TInfEq earith_expr { logic_op Ast.InfEq $1 $2 $3 }
602 | earith_expr TSupEq earith_expr { logic_op Ast.SupEq $1 $2 $3 }
603 | earith_expr TEqEq earith_expr { logic_op Ast.Eq $1 $2 $3 }
604 | earith_expr TNotEq earith_expr { logic_op Ast.NotEq $1 $2 $3 }
605 | earith_expr TAnd earith_expr { arith_op Ast.And $1 $2 $3 }
606 | earith_expr TOr earith_expr { arith_op Ast.Or $1 $2 $3 }
607 | earith_expr TXor earith_expr { arith_op Ast.Xor $1 $2 $3 }
608 | earith_expr TAndLog earith_expr { logic_op Ast.AndLog $1 $2 $3 }
609 | earith_expr TOrLog earith_expr { logic_op Ast.OrLog $1 $2 $3 }
610
611 ecast_expr: eunary_expr { $1 }
612 | TOPar ctype TCPar ecast_expr
613 { Ast0.Cast (clt2mcode "(" $1, $2, clt2mcode ")" $3, $4) }
614
615 eunary_expr: epostfix_expr { $1 }
616 | TInc eunary_expr
617 { Ast0.Infix ($2, clt2mcode Ast.Inc $1) }
618 | TDec eunary_expr
619 { Ast0.Infix ($2, clt2mcode Ast.Dec $1) }
620 | unary_op eunary_expr
621 { let mcode = $1 in Ast0.Unary($2, mcode) }
622
623 epostfix_expr: eprimary_expr { $1 }
624 | epostfix_expr TOCro eexpr TCCro
625 { Ast0.ArrayAccess ($1,clt2mcode "[" $2,$3,clt2mcode "]" $4) }
626 | epostfix_expr TDot ident
627 { Ast0.RecordAccess($1, clt2mcode "." $2, $3) }
628 | epostfix_expr TPtrOp ident
629 { Ast0.RecordPtAccess($1, clt2mcode "->" $2, $3) }
630 | epostfix_expr TInc
631 { Ast0.Postfix ($1, clt2mcode Ast.Inc $2) }
632 | epostfix_expr TDec
633 { Ast0.Postfix ($1, clt2mcode Ast.Dec $2) }
634 | epostfix_expr TOPar eexpr_list_opt TCPar
635 { Ast0.FunCall($1,clt2mcode "(" $2,$3,clt2mcode ")" $4) }
636
637 eprimary_expr: ident { Ast0.Ident($1) }
638 | TEllipsis { Ast0.Edots(clt2mcode "..." $1,None) }
639 | TInt
640 { let (x,clt) = $1 in
641 Ast0.Constant (clt2mcode (Ast.Int x) clt) }
642 | TFloat
643 { let (x,clt) = $1 in
644 Ast0.Constant (clt2mcode (Ast.Float x) clt) }
645 | TString
646 { let (x,clt) = $1 in
647 Ast0.Constant (clt2mcode (Ast.String x) clt) }
648 | TChar
649 { let (x,clt) = $1 in
650 Ast0.Constant (clt2mcode (Ast.Char x) clt) }
651 | TMetaConst
652 { let (nm,ty,clt) = $1 in Ast0.MetaConst(clt2mcode nm clt,ty) }
653 | TMetaErr
654 { let (nm,clt) = $1 in Ast0.MetaErr(clt2mcode nm clt) }
655 | TMetaExp
656 { let (nm,ty,clt) = $1 in Ast0.MetaExpr(clt2mcode nm clt,ty) }
657 | TOPar eexpr TCPar
658 { Ast0.Paren(clt2mcode "(" $1,$2,clt2mcode ")" $3) }
659 | TOPar0 eexpr_mid TCPar0
660 { Ast0.DisjExpr($2) }
661 | TOEllipsis expr_dots TCEllipsis
662 { Ast0.NestExpr(Ast0.DOTS($2)) }
663 | TOCircles expr_circles TCCircles
664 { Ast0.NestExpr(Ast0.CIRCLES($2)) }
665 | TOStars expr_stars TCStars
666 { Ast0.NestExpr(Ast0.STARS($2)) }
667
668 /*****************************************************************************/
669
670 dexpr: dassign_expr { $1 }
671
672 dassign_expr: dcond_expr { $1 }
673 | dunary_expr TAssign dassign_expr
674 { let (op,clt) = $2 in
675 Ast0.Assignment($1,clt2mcode op clt,$3) }
676 | dunary_expr TEq dassign_expr
677 { Ast0.Assignment($1,clt2mcode Ast.SimpleAssign $2,$3) }
678
679 dcond_expr: darith_expr { $1 }
680 | darith_expr TWhy eexpr_opt TDotDot dcond_expr
681 { Ast0.CondExpr ($1, clt2mcode "?" $2, $3, clt2mcode "?" $4, $5) }
682
683 darith_expr: dcast_expr { $1 }
684 | darith_expr TMul darith_expr { arith_op Ast.Mul $1 $2 $3 }
685 | darith_expr TDiv darith_expr { arith_op Ast.Div $1 $2 $3 }
686 | darith_expr TMod darith_expr { arith_op Ast.Mod $1 $2 $3 }
687 | darith_expr TPlus darith_expr { arith_op Ast.Plus $1 $2 $3 }
688 | darith_expr TMinus darith_expr { arith_op Ast.Minus $1 $2 $3 }
689 | darith_expr TShl darith_expr { arith_op Ast.DecLeft $1 $2 $3 }
690 | darith_expr TShr darith_expr { arith_op Ast.DecRight $1 $2 $3 }
691 | darith_expr TInf darith_expr { logic_op Ast.Inf $1 $2 $3 }
692 | darith_expr TSup darith_expr { logic_op Ast.Sup $1 $2 $3 }
693 | darith_expr TInfEq darith_expr { logic_op Ast.InfEq $1 $2 $3 }
694 | darith_expr TSupEq darith_expr { logic_op Ast.SupEq $1 $2 $3 }
695 | darith_expr TEqEq darith_expr { logic_op Ast.Eq $1 $2 $3 }
696 | darith_expr TNotEq darith_expr { logic_op Ast.NotEq $1 $2 $3 }
697 | darith_expr TAnd darith_expr { arith_op Ast.And $1 $2 $3 }
698 | darith_expr TOr darith_expr { arith_op Ast.Or $1 $2 $3 }
699 | darith_expr TXor darith_expr { arith_op Ast.Xor $1 $2 $3 }
700 | darith_expr TAndLog darith_expr { logic_op Ast.AndLog $1 $2 $3 }
701 | darith_expr TOrLog darith_expr { logic_op Ast.OrLog $1 $2 $3 }
702
703 dcast_expr: dunary_expr { $1 }
704 | TOPar ctype TCPar dcast_expr
705 { Ast0.Cast (clt2mcode "(" $1, $2, clt2mcode ")" $3, $4) }
706
707 dunary_expr: dpostfix_expr { $1 }
708 | TInc dunary_expr
709 { Ast0.Infix ($2, clt2mcode Ast.Inc $1) }
710 | TDec dunary_expr
711 { Ast0.Infix ($2, clt2mcode Ast.Dec $1) }
712 | unary_op dunary_expr
713 { let mcode = $1 in Ast0.Unary($2, mcode) }
714
715 dpostfix_expr: dprimary_expr { $1 }
716 | dpostfix_expr TOCro eexpr TCCro
717 { Ast0.ArrayAccess ($1,clt2mcode "[" $2,$3,clt2mcode "]" $4) }
718 | dpostfix_expr TDot ident
719 { Ast0.RecordAccess($1, clt2mcode "." $2, $3) }
720 | dpostfix_expr TPtrOp ident
721 { Ast0.RecordPtAccess($1, clt2mcode "->" $2, $3) }
722 | dpostfix_expr TInc
723 { Ast0.Postfix ($1, clt2mcode Ast.Inc $2) }
724 | dpostfix_expr TDec
725 { Ast0.Postfix ($1, clt2mcode Ast.Dec $2) }
726 | dpostfix_expr TOPar eexpr_list_opt TCPar
727 { Ast0.FunCall($1,clt2mcode "(" $2,$3,clt2mcode ")" $4) }
728
729 dprimary_expr: ident { Ast0.Ident($1) }
730 | TInt
731 { let (x,clt) = $1 in
732 Ast0.Constant (clt2mcode (Ast.Int x) clt) }
733 | TFloat
734 { let (x,clt) = $1 in
735 Ast0.Constant (clt2mcode (Ast.Float x) clt) }
736 | TString
737 { let (x,clt) = $1 in
738 Ast0.Constant (clt2mcode (Ast.String x) clt) }
739 | TChar
740 { let (x,clt) = $1 in
741 Ast0.Constant (clt2mcode (Ast.Char x) clt) }
742 | TMetaConst
743 { let (nm,ty,clt) = $1 in Ast0.MetaConst(clt2mcode nm clt,ty) }
744 | TMetaErr
745 { let (nm,clt) = $1 in Ast0.MetaErr(clt2mcode nm clt) }
746 | TMetaExp
747 { let (nm,ty,clt) = $1 in Ast0.MetaExpr(clt2mcode nm clt,ty) }
748 | TOPar eexpr TCPar
749 { Ast0.Paren(clt2mcode "(" $1,$2,clt2mcode ")" $3) }
750 | TOPar0 eexpr_mid TCPar0
751 { Ast0.DisjExpr($2) }
752 | TOEllipsis expr_dots TCEllipsis
753 { Ast0.NestExpr(Ast0.DOTS($2)) }
754 | TOCircles expr_circles TCCircles
755 { Ast0.NestExpr(Ast0.CIRCLES($2)) }
756 | TOStars expr_stars TCStars
757 { Ast0.NestExpr(Ast0.STARS($2)) }
758
759 expr_dots:
760 dexpr { [$1] }
761 | dexpr TEllipsis expr_dots
762 { $1 :: Ast0.Edots(clt2mcode "..." $2,None) :: $3 }
763 | dexpr TEllipsis TWhen TNotEq eexpr TLineEnd expr_dots
764 { $1 :: Ast0.Edots(clt2mcode "..." $2,Some $5) :: $7 }
765
766 expr_circles:
767 dexpr { [$1] }
768 | dexpr TCircles expr_circles
769 { $1 :: Ast0.Ecircles(clt2mcode "ooo" $2,None) :: $3 }
770 | dexpr TCircles TWhen TNotEq eexpr TLineEnd expr_dots
771 { $1 :: Ast0.Ecircles(clt2mcode "ooo" $2,Some $5) :: $7 }
772
773 expr_stars:
774 dexpr { [$1] }
775 | dexpr TStars expr_stars
776 { $1 :: Ast0.Estars(clt2mcode "***" $2,None) :: $3 }
777 | dexpr TStars TWhen TNotEq eexpr TLineEnd expr_dots
778 { $1 :: Ast0.Estars(clt2mcode "***" $2,Some $5) :: $7 }
779
780 /*****************************************************************************/
781
782 pure_ident: TIdent { $1 }
783
784 /* allows redeclaring metavariables. used in @@ @@ */
785 pure_ident_or_meta_ident:
786 TIdent { $1 }
787 | TMetaId { $1 }
788 | TMetaType { $1 }
789 | TMetaParam { $1 }
790 | TMetaParamList { $1 }
791 | TMetaStm { $1 }
792 | TMetaStmList { $1 }
793 | TMetaFunc { $1 }
794 | TMetaLocalFunc { $1 }
795 | TMetaExpList { $1 }
796 | TMetaConst { let (name,_,info) = $1 in (name,info) }
797 | TMetaExp { let (name,_,info) = $1 in (name,info) }
798 | TMetaErr { $1 }
799
800 ident: TIdent { Ast0.Id(id2mcode $1) }
801 | TMetaId { Ast0.MetaId(id2mcode $1) }
802 | TMetaFunc { Ast0.MetaFunc(id2mcode $1) }
803 | TMetaLocalFunc { Ast0.MetaLocalFunc(id2mcode $1) }
804
805 /*****************************************************************************/
806
807 meta_var_list: meta_var { $1 }
808 | meta_var meta_var_list { $1@$2 }
809
810 meta_var_list_opt: meta_var_list { $1 }
811 | /* empty */ { [] }
812
813 d_ident_list: d_ident { [$1] }
814 | d_ident TComma d_ident_list { $1::$3 }
815
816 ctype_list: ctype { [$1] }
817 | ctype TComma ctype_list { $1::$3 }
818
819 pure_ident_or_meta_ident_list:
820 pure_ident_or_meta_ident
821 { [id2name $1] }
822 | pure_ident_or_meta_ident TComma pure_ident_or_meta_ident_list
823 { (id2name $1)::$3 }
824
825 decl_list:
826 decl_list_start
827 { if List.exists (function Ast0.Pcircles(_) -> true | _ -> false) $1
828 then Ast0.CIRCLES($1)
829 else Ast0.DOTS($1) }
830
831 decl_list_start:
832 decl { [$1] }
833 | TMetaParamList
834 { let (nm,clt) = $1 in [Ast0.MetaParamList(clt2mcode nm clt)] }
835 | TEllipsis
836 { [Ast0.Pdots(clt2mcode "..." $1)] }
837 | TCircles
838 { [Ast0.Pcircles(clt2mcode "ooo" $1)] }
839 | decl TComma decl_list_start
840 { $1::Ast0.PComma(clt2mcode "," $2)::$3 }
841 | TMetaParamList TComma decl_list_start
842 { let (nm,clt) = $1 in
843 Ast0.MetaParamList(clt2mcode nm clt)::
844 Ast0.PComma(clt2mcode "," $2)::$3 }
845 | TEllipsis TComma decl_list_dots
846 { Ast0.Pdots(clt2mcode "..." $1)::
847 Ast0.PComma(clt2mcode "," $2)::
848 $3 }
849 | TCircles TComma decl_list_circles
850 { Ast0.Pcircles(clt2mcode "ooo" $1)::
851 Ast0.PComma(clt2mcode "," $2)::
852 $3 }
853
854 decl_list_dots:
855 decl { [$1] }
856 | TMetaParamList
857 { let (nm,clt) = $1 in [Ast0.MetaParamList(clt2mcode nm clt)] }
858 | TEllipsis
859 { [Ast0.Pdots(clt2mcode "..." $1)] }
860 | decl TComma decl_list_dots
861 { $1::Ast0.PComma(clt2mcode "," $2)::$3 }
862 | TMetaParamList TComma decl_list_dots
863 { let (nm,clt) = $1 in
864 Ast0.MetaParamList(clt2mcode nm clt)::
865 Ast0.PComma(clt2mcode "," $2)::$3 }
866 | TEllipsis TComma decl_list_dots
867 { Ast0.Pdots(clt2mcode "..." $1)::Ast0.PComma(clt2mcode "," $2)::
868 $3 }
869
870 decl_list_circles:
871 decl { [$1] }
872 | TMetaParamList
873 { let (nm,clt) = $1 in [Ast0.MetaParamList(clt2mcode nm clt)] }
874 | TCircles
875 { [Ast0.Pcircles(clt2mcode "ooo" $1)] }
876 | decl TComma decl_list_circles
877 { $1::Ast0.PComma(clt2mcode "," $2)::$3 }
878 | TMetaParamList TComma decl_list_circles
879 { let (nm,clt) = $1 in
880 Ast0.MetaParamList(clt2mcode nm clt)::
881 Ast0.PComma(clt2mcode "," $2)::$3 }
882 | TCircles TComma decl_list_circles
883 { Ast0.Pcircles(clt2mcode "ooo" $1)::
884 Ast0.PComma(clt2mcode "," $2)::
885 $3 }
886
887 /* must be a single statement */
888 statement_mid:
889 statement { [Ast0.DOTS([$1])] }
890 | statement TMid0 statement_mid { Ast0.DOTS([$1])::$3 }
891
892 /* must be a list of declarations or statements, with no ... or expressions
893 for "and" case */
894 pure_decl_statement_list:
895 decl_statement { $1 }
896 | decl_statement pure_decl_statement_list { $1@$2 }
897
898 /* as above, but allows a single expression - for "or" case */
899 exp_decl_statement_list:
900 expr { [Ast0.Exp($1)] }
901 | decl_statement { $1 }
902 | decl_statement pure_decl_statement_list { $1@$2 }
903
904 fun_exp_decl_statement_list:
905 expr
906 { [Ast0.OTHER(Ast0.Exp($1))] }
907 | decl_statement
908 { List.map (function x -> Ast0.OTHER x) $1 }
909 | fundecl
910 { [Ast0.FUNCTION($1)] }
911 | TInclude
912 { [Ast0.INCLUDE(clt2mcode "#include" (id2clt $1),id2mcode $1)] }
913 | TMinusFile TPlusFile
914 { [Ast0.FILEINFO(id2mcode $1,id2mcode $2)] }
915 | decl_statement fun_exp_decl_statement_list
916 { (List.map (function x -> Ast0.OTHER x) $1)@$2 }
917 | fundecl fun_exp_decl_statement_list
918 { Ast0.FUNCTION($1)::$2 }
919 | TInclude fun_exp_decl_statement_list
920 { Ast0.INCLUDE(clt2mcode "#include" (id2clt $1),id2mcode $1)::$2 }
921 | TMinusFile TPlusFile fun_exp_decl_statement_list
922 { Ast0.FILEINFO(id2mcode $1,id2mcode $2)::$3 }
923
924 /* ---------------------------------------------------------------------- */
925
926 error_words:
927 TError TWords TEq TOCro dotless_eexpr_list TCCro
928 { Ast0.ERRORWORDS($5) }
929
930 /* ---------------------------------------------------------------------- */
931 /* sequences of statements and expressions */
932
933 /* a mix of declarations, statements and expressions. an expression may
934 appear by itself. always nonempty and cannot just be dots. */
935
936 function_decl_statement_or_expression:
937 error_words /* only at the end */
938 { [$1] }
939 | fun_exp_decl_statement_list
940 { $1 }
941 | fun_exp_decl_statement_list TEllipsis
942 function_decl_statement_or_expression_dots
943 { $1@Ast0.OTHER(Ast0.Dots(clt2mcode "..." $2,None))::$3 }
944 | TEllipsis function_decl_statement_or_expression_dots
945 { Ast0.OTHER(Ast0.Dots(clt2mcode "..." $1,None))::$2 }
946 | fun_exp_decl_statement_list TEllipsis
947 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
948 function_decl_statement_or_expression_dots
949 { $1@Ast0.OTHER(Ast0.Dots(clt2mcode "..." $2,Some $5))::$7 }
950 | TEllipsis TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
951 function_decl_statement_or_expression_dots
952 { Ast0.OTHER(Ast0.Dots(clt2mcode "..." $2,Some $4))::$6 }
953 | fun_exp_decl_statement_list TCircles
954 function_decl_statement_or_expression_circles
955 { $1@Ast0.OTHER(Ast0.Circles(clt2mcode "ooo" $2,None))::$3 }
956 | TCircles function_decl_statement_or_expression_circles
957 { Ast0.OTHER(Ast0.Circles(clt2mcode "ooo" $1,None))::$2 }
958 | fun_exp_decl_statement_list TCircles
959 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
960 function_decl_statement_or_expression_circles
961 { $1@Ast0.OTHER(Ast0.Circles(clt2mcode "ooo" $2,Some $5))::$7 }
962 | TCircles TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
963 function_decl_statement_or_expression_circles
964 { Ast0.OTHER(Ast0.Circles(clt2mcode "ooo" $1,Some $4))::$6 }
965 | fun_exp_decl_statement_list TStars
966 function_decl_statement_or_expression_stars
967 { $1@Ast0.OTHER(Ast0.Stars(clt2mcode "***" $2,None))::$3 }
968 | TStars function_decl_statement_or_expression_stars
969 { Ast0.OTHER(Ast0.Stars(clt2mcode "***" $1,None))::$2 }
970 | fun_exp_decl_statement_list TStars
971 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
972 function_decl_statement_or_expression_stars
973 { $1@Ast0.OTHER(Ast0.Stars(clt2mcode "***" $2,Some $5))::$7 }
974 | TStars TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
975 function_decl_statement_or_expression_stars
976 { Ast0.OTHER(Ast0.Stars(clt2mcode "***" $1,Some $4))::$6 }
977
978 function_decl_statement_or_expression_dots:
979 /* empty */ { [] }
980 | fun_exp_decl_statement_list
981 { $1 }
982 | fun_exp_decl_statement_list TEllipsis
983 function_decl_statement_or_expression_dots
984 { $1@Ast0.OTHER(Ast0.Dots(clt2mcode "..." $2,None))::$3 }
985 | fun_exp_decl_statement_list TEllipsis
986 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
987 function_decl_statement_or_expression_dots
988 { $1@Ast0.OTHER(Ast0.Dots(clt2mcode "..." $2,Some $5))::$7 }
989
990 function_decl_statement_or_expression_circles:
991 /* empty */ { [] }
992 | fun_exp_decl_statement_list
993 { $1 }
994 | fun_exp_decl_statement_list TCircles
995 function_decl_statement_or_expression_circles
996 { $1@Ast0.OTHER(Ast0.Circles(clt2mcode "ooo" $2,None))::$3 }
997 | fun_exp_decl_statement_list TCircles
998 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
999 function_decl_statement_or_expression_circles
1000 { $1@Ast0.OTHER(Ast0.Circles(clt2mcode "ooo" $2,Some $5))::$7 }
1001
1002 function_decl_statement_or_expression_stars:
1003 /* empty */ { [] }
1004 | fun_exp_decl_statement_list
1005 { $1 }
1006 | fun_exp_decl_statement_list TStars
1007 function_decl_statement_or_expression_stars
1008 { $1@Ast0.OTHER(Ast0.Stars(clt2mcode "***" $2,None))::$3 }
1009 | fun_exp_decl_statement_list TStars
1010 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1011 function_decl_statement_or_expression_stars
1012 { $1@Ast0.OTHER(Ast0.Stars(clt2mcode "***" $2,Some $5))::$7 }
1013
1014 decl_statement_or_expression_dots:
1015 exp_decl_statement_list
1016 { $1 }
1017 | exp_decl_statement_list TEllipsis decl_statement_or_expression_dots
1018 { $1@Ast0.Dots(clt2mcode "..." $2,None)::$3 }
1019 | exp_decl_statement_list TEllipsis
1020 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1021 decl_statement_or_expression_dots
1022 { $1@Ast0.Dots(clt2mcode "..." $2,Some $5)::$7 }
1023
1024 decl_statement_or_expression_circles:
1025 exp_decl_statement_list
1026 { $1 }
1027 | exp_decl_statement_list TCircles decl_statement_or_expression_circles
1028 { $1@Ast0.Dots(clt2mcode "..." $2,None)::$3 }
1029 | exp_decl_statement_list TCircles
1030 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1031 decl_statement_or_expression_circles
1032 { $1@Ast0.Dots(clt2mcode "..." $2,Some $5)::$7 }
1033
1034 decl_statement_or_expression_stars:
1035 exp_decl_statement_list
1036 { $1 }
1037 | exp_decl_statement_list TStars decl_statement_or_expression_stars
1038 { $1@Ast0.Stars(clt2mcode "***" $2,None)::$3 }
1039 | exp_decl_statement_list TStars
1040 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1041 decl_statement_or_expression_stars
1042 { $1@Ast0.Stars(clt2mcode "***" $2,Some $5)::$7 }
1043
1044 post_decl_statement_or_expression:
1045 exp_decl_statement_list
1046 { $1 }
1047 | exp_decl_statement_list TEllipsis
1048 { $1@[Ast0.Dots(clt2mcode "..." $2,None)] }
1049 | exp_decl_statement_list TEllipsis
1050 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1051 { $1@[Ast0.Dots(clt2mcode "..." $2,Some $5)] }
1052 | exp_decl_statement_list TCircles
1053 { $1@[Ast0.Circles(clt2mcode "ooo" $2,None)] }
1054 | exp_decl_statement_list TCircles
1055 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1056 { $1@[Ast0.Circles(clt2mcode "ooo" $2,Some $5)] }
1057 | exp_decl_statement_list TStars
1058 { $1@[Ast0.Stars(clt2mcode "***" $2,None)] }
1059 | exp_decl_statement_list TStars
1060 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1061 { $1@[Ast0.Stars(clt2mcode "***" $2,Some $5)] }
1062 | exp_decl_statement_list TEllipsis post_decl_statement_or_expression_dots
1063 { $1@Ast0.Dots(clt2mcode "..." $2,None)::$3 }
1064 | exp_decl_statement_list TEllipsis
1065 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1066 post_decl_statement_or_expression_dots
1067 { $1@Ast0.Dots(clt2mcode "..." $2,Some $5)::$7 }
1068 | exp_decl_statement_list TCircles post_decl_statement_or_expression_dots
1069 { $1@Ast0.Circles(clt2mcode "ooo" $2,None)::$3 }
1070 | exp_decl_statement_list TCircles
1071 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1072 post_decl_statement_or_expression_dots
1073 { $1@Ast0.Circles(clt2mcode "ooo" $2,Some $5)::$7 }
1074 | exp_decl_statement_list TStars post_decl_statement_or_expression_dots
1075 { $1@Ast0.Stars(clt2mcode "***" $2,None)::$3 }
1076 | exp_decl_statement_list TStars
1077 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1078 post_decl_statement_or_expression_dots
1079 { $1@Ast0.Stars(clt2mcode "***" $2,Some $5)::$7 }
1080
1081 post_decl_statement_or_expression_dots:
1082 exp_decl_statement_list
1083 { $1 }
1084 | exp_decl_statement_list TEllipsis
1085 { $1@[Ast0.Dots(clt2mcode "..." $2,None)] }
1086 | exp_decl_statement_list TEllipsis
1087 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1088 { $1@[Ast0.Dots(clt2mcode "..." $2,Some $5)] }
1089 | exp_decl_statement_list TEllipsis post_decl_statement_or_expression_dots
1090 { $1@Ast0.Dots(clt2mcode "..." $2,None)::$3 }
1091 | exp_decl_statement_list TEllipsis
1092 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1093 post_decl_statement_or_expression_dots
1094 { $1@Ast0.Dots(clt2mcode "..." $2,Some $5)::$7 }
1095
1096 post_decl_statement_or_expression_circles:
1097 exp_decl_statement_list
1098 { $1 }
1099 | exp_decl_statement_list TCircles
1100 { $1@[Ast0.Circles(clt2mcode "ooo" $2,None)] }
1101 | exp_decl_statement_list TCircles
1102 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1103 { $1@[Ast0.Circles(clt2mcode "ooo" $2,Some $5)] }
1104 | exp_decl_statement_list TCircles post_decl_statement_or_expression_circles
1105 { $1@Ast0.Circles(clt2mcode "ooo" $2,None)::$3 }
1106 | exp_decl_statement_list TCircles
1107 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1108 post_decl_statement_or_expression_circles
1109 { $1@Ast0.Circles(clt2mcode "ooo" $2,Some $5)::$7 }
1110
1111 post_decl_statement_or_expression_stars:
1112 exp_decl_statement_list
1113 { $1 }
1114 | exp_decl_statement_list TEllipsis
1115 { $1@[Ast0.Stars(clt2mcode "***" $2,None)] }
1116 | exp_decl_statement_list TEllipsis
1117 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1118 { $1@[Ast0.Stars(clt2mcode "***" $2,Some $5)] }
1119 | exp_decl_statement_list TEllipsis post_decl_statement_or_expression_stars
1120 { $1@Ast0.Stars(clt2mcode "***" $2,None)::$3 }
1121 | exp_decl_statement_list TEllipsis
1122 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1123 post_decl_statement_or_expression_stars
1124 { $1@Ast0.Stars(clt2mcode "***" $2,Some $5)::$7 }
1125
1126 pre_post_decl_statement_or_expression:
1127 post_decl_statement_or_expression
1128 { if List.exists (function Ast0.Circles(_) -> true | _ -> false) $1
1129 then Ast0.CIRCLES($1)
1130 else if List.exists (function Ast0.Stars(_) -> true | _ -> false) $1
1131 then Ast0.STARS($1)
1132 else Ast0.DOTS($1) }
1133 | TEllipsis post_decl_statement_or_expression_dots
1134 { Ast0.DOTS(Ast0.Dots(clt2mcode "..." $1,None)::$2) }
1135 | TEllipsis TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1136 post_decl_statement_or_expression_dots
1137 { Ast0.DOTS(Ast0.Dots(clt2mcode "..." $1,Some $4)::$6) }
1138 | TCircles post_decl_statement_or_expression_circles
1139 { Ast0.CIRCLES(Ast0.Circles(clt2mcode "ooo" $1,None)::$2) }
1140 | TCircles TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1141 post_decl_statement_or_expression_circles
1142 { Ast0.CIRCLES(Ast0.Circles(clt2mcode "ooo" $1,Some $4)::$6) }
1143 | TStars post_decl_statement_or_expression_stars
1144 { Ast0.STARS(Ast0.Stars(clt2mcode "***" $1,None)::$2) }
1145 | TStars TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1146 post_decl_statement_or_expression_stars
1147 { Ast0.STARS(Ast0.Stars(clt2mcode "***" $1,Some $4)::$6) }
1148
1149 /* a mix of declarations, statements and expressions. an expression must
1150 be surrounded by ... */
1151
1152 post_decl_statement_and_expression_dots:
1153 /* empty */ { [] }
1154 | pure_decl_statement_list { $1 }
1155 | expr TEllipsis post_decl_statement_and_expression_dots
1156 { Ast0.Exp($1)::Ast0.Dots(clt2mcode "..." $2,None)::$3 }
1157 | expr TEllipsis
1158 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1159 post_decl_statement_and_expression_dots
1160 { Ast0.Exp($1)::Ast0.Dots(clt2mcode "..." $2,Some $5)::$7 }
1161 | pure_decl_statement_list TEllipsis post_decl_statement_and_expression_dots
1162 { $1@Ast0.Dots(clt2mcode "..." $2,None)::$3 }
1163 | pure_decl_statement_list TEllipsis
1164 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1165 post_decl_statement_and_expression_dots
1166 { $1@Ast0.Dots(clt2mcode "..." $2,Some $5)::$7 }
1167
1168 post_decl_statement_and_expression_circles:
1169 /* empty */ { [] }
1170 | pure_decl_statement_list { $1 }
1171 | expr TCircles post_decl_statement_and_expression_circles
1172 { Ast0.Exp($1)::Ast0.Circles(clt2mcode "ooo" $2,None)::$3 }
1173 | expr TCircles
1174 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1175 post_decl_statement_and_expression_circles
1176 { Ast0.Exp($1)::Ast0.Circles(clt2mcode "ooo" $2,Some $5)::$7 }
1177 | pure_decl_statement_list TCircles
1178 post_decl_statement_and_expression_circles
1179 { $1@Ast0.Circles(clt2mcode "ooo" $2,None)::$3 }
1180 | pure_decl_statement_list TCircles
1181 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1182 post_decl_statement_and_expression_circles
1183 { $1@Ast0.Circles(clt2mcode "ooo" $2,Some $5)::$7 }
1184
1185 post_decl_statement_and_expression_stars:
1186 /* empty */ { [] }
1187 | pure_decl_statement_list { $1 }
1188 | expr TStars post_decl_statement_and_expression_stars
1189 { Ast0.Exp($1)::Ast0.Stars(clt2mcode "***" $2,None)::$3 }
1190 | expr TStars
1191 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1192 post_decl_statement_and_expression_stars
1193 { Ast0.Exp($1)::Ast0.Stars(clt2mcode "***" $2,Some $5)::$7 }
1194 | pure_decl_statement_list TStars post_decl_statement_and_expression_stars
1195 { $1@Ast0.Stars(clt2mcode "***" $2,None)::$3 }
1196 | pure_decl_statement_list TStars
1197 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1198 post_decl_statement_and_expression_stars
1199 { $1@Ast0.Stars(clt2mcode "***" $2,Some $5)::$7 }
1200
1201 pre_post_decl_statement_and_expression:
1202 pure_decl_statement_list
1203 { top_dots $1 }
1204 | pure_decl_statement_list TEllipsis post_decl_statement_and_expression_dots
1205 { Ast0.DOTS($1@Ast0.Dots(clt2mcode "..." $2,None)::$3) }
1206 | pure_decl_statement_list TEllipsis
1207 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1208 post_decl_statement_and_expression_dots
1209 { Ast0.DOTS($1@Ast0.Dots(clt2mcode "..." $2,Some $5)::$7) }
1210 | pure_decl_statement_list TCircles
1211 post_decl_statement_and_expression_circles
1212 { Ast0.CIRCLES($1@Ast0.Circles(clt2mcode "ooo" $2,None)::$3) }
1213 | pure_decl_statement_list TCircles
1214 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1215 post_decl_statement_and_expression_circles
1216 { Ast0.CIRCLES($1@Ast0.Circles(clt2mcode "ooo" $2,Some $5)::$7) }
1217 | pure_decl_statement_list TStars post_decl_statement_and_expression_stars
1218 { Ast0.STARS($1@Ast0.Stars(clt2mcode "***" $2,None)::$3) }
1219 | pure_decl_statement_list TStars
1220 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1221 post_decl_statement_and_expression_stars
1222 { Ast0.STARS($1@Ast0.Stars(clt2mcode "***" $2,Some $5)::$7) }
1223 | TEllipsis post_decl_statement_and_expression_dots
1224 { Ast0.DOTS(Ast0.Dots(clt2mcode "..." $1,None)::$2) }
1225 | TEllipsis
1226 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1227 post_decl_statement_and_expression_dots
1228 { Ast0.DOTS(Ast0.Dots(clt2mcode "..." $1,Some $4)::$6) }
1229 | TCircles post_decl_statement_and_expression_circles
1230 { Ast0.CIRCLES(Ast0.Circles(clt2mcode "ooo" $1,None)::$2) }
1231 | TCircles
1232 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1233 post_decl_statement_and_expression_circles
1234 { Ast0.CIRCLES(Ast0.Circles(clt2mcode "ooo" $1,Some $4)::$6) }
1235 | TStars post_decl_statement_and_expression_stars
1236 { Ast0.STARS(Ast0.Stars(clt2mcode "***" $1,None)::$2) }
1237 | TStars
1238 TWhen TNotEq pre_post_decl_statement_or_expression TLineEnd
1239 post_decl_statement_and_expression_stars
1240 { Ast0.STARS(Ast0.Stars(clt2mcode "***" $1,Some $4)::$6) }
1241
1242 pre_post_decl_statement_and_expression_opt:
1243 /* empty */ { Ast0.DOTS([]) }
1244 | pre_post_decl_statement_and_expression { $1 }
1245
1246 pre_post_decl_statement_and_expression_opt_mid:
1247 pre_post_decl_statement_and_expression { [$1] }
1248 | /* empty */ { [Ast0.DOTS([])] }
1249 | pre_post_decl_statement_and_expression TMid0
1250 pre_post_decl_statement_and_expression_opt_mid { $1::$3 }
1251 | TMid0
1252 pre_post_decl_statement_and_expression_opt_mid { Ast0.DOTS([])::$2 }
1253
1254 /* ---------------------------------------------------------------------- */
1255
1256 dotless_eexpr_list:
1257 dexpr
1258 { [$1] }
1259 | dexpr TComma dotless_eexpr_list
1260 { $1::Ast0.EComma(clt2mcode "," $2)::$3 }
1261
1262 eexpr_list:
1263 eexpr_list_start
1264 { if List.exists (function Ast0.Ecircles(_) -> true | _ -> false) $1
1265 then Ast0.CIRCLES($1)
1266 else if List.exists (function Ast0.Estars(_) -> true | _ -> false) $1
1267 then Ast0.STARS($1)
1268 else Ast0.DOTS($1) }
1269
1270 eexpr_list_start:
1271 dexpr
1272 { [$1] }
1273 | TMetaExpList
1274 { let (nm,clt) = $1 in [Ast0.MetaExprList(clt2mcode nm clt)] }
1275 | TEllipsis
1276 { [Ast0.Edots(clt2mcode "..." $1,None)] }
1277 | TEllipsis TWhen TNotEq eexpr TLineEnd
1278 { [Ast0.Edots(clt2mcode "..." $1,Some $4)] }
1279 | TCircles
1280 { [Ast0.Ecircles(clt2mcode "ooo" $1,None)] }
1281 | TCircles TWhen TNotEq eexpr TLineEnd
1282 { [Ast0.Ecircles(clt2mcode "ooo" $1,Some $4)] }
1283 | TStars
1284 { [Ast0.Estars(clt2mcode "***" $1,None)] }
1285 | TStars TWhen TNotEq eexpr TLineEnd
1286 { [Ast0.Estars(clt2mcode "***" $1,Some $4)] }
1287 | dexpr TComma eexpr_list_start
1288 { $1::Ast0.EComma(clt2mcode "," $2)::$3 }
1289 | TMetaExpList TComma eexpr_list_start
1290 { let (nm,clt) = $1 in
1291 Ast0.MetaExprList(clt2mcode nm clt)::Ast0.EComma(clt2mcode "," $2)::$3 }
1292 | TEllipsis TComma eexpr_list_dots
1293 { Ast0.Edots(clt2mcode "..." $1,None)::
1294 Ast0.EComma(clt2mcode "," $2)::$3 }
1295 | TEllipsis TWhen TNotEq eexpr TLineEnd TComma eexpr_list_dots
1296 { Ast0.Edots(clt2mcode "..." $1,Some $4)::
1297 Ast0.EComma(clt2mcode "," $6)::$7 }
1298 | TCircles TComma eexpr_list_circles
1299 { Ast0.Ecircles(clt2mcode "ooo" $1,None)::
1300 Ast0.EComma(clt2mcode "," $2)::$3 }
1301 | TCircles TWhen TNotEq eexpr TLineEnd TComma eexpr_list_circles
1302 { Ast0.Ecircles(clt2mcode "ooo" $1,Some $4)::
1303 Ast0.EComma(clt2mcode "," $6)::$7 }
1304 | TStars TComma eexpr_list_stars
1305 { Ast0.Estars(clt2mcode "***" $1,None)::
1306 Ast0.EComma(clt2mcode "," $2)::$3 }
1307 | TStars TWhen TNotEq eexpr TLineEnd TComma eexpr_list_stars
1308 { Ast0.Estars(clt2mcode "***" $1,Some $4)::
1309 Ast0.EComma(clt2mcode "," $6)::$7 }
1310
1311 eexpr_list_dots:
1312 dexpr
1313 { [$1] }
1314 | TMetaExpList
1315 { let (nm,clt) = $1 in [Ast0.MetaExprList(clt2mcode nm clt)] }
1316 | TEllipsis
1317 { [Ast0.Edots(clt2mcode "..." $1,None)] }
1318 | TEllipsis TWhen TNotEq eexpr TLineEnd
1319 { [Ast0.Edots(clt2mcode "..." $1,Some $4)] }
1320 | dexpr TComma eexpr_list_dots
1321 { $1::Ast0.EComma(clt2mcode "," $2)::$3 }
1322 | TMetaExpList TComma eexpr_list_dots
1323 { let (nm,clt) = $1 in
1324 Ast0.MetaExprList(clt2mcode nm clt)::Ast0.EComma(clt2mcode "," $2)::$3 }
1325 | TEllipsis TComma eexpr_list_dots
1326 { Ast0.Edots(clt2mcode "..." $1,None)::
1327 Ast0.EComma(clt2mcode "," $2)::$3 }
1328 | TEllipsis TWhen TNotEq eexpr TLineEnd TComma eexpr_list_dots
1329 { Ast0.Edots(clt2mcode "..." $1,Some $4)::
1330 Ast0.EComma(clt2mcode "," $6)::$7 }
1331
1332 eexpr_list_circles:
1333 dexpr
1334 { [$1] }
1335 | TMetaExpList
1336 { let (nm,clt) = $1 in [Ast0.MetaExprList(clt2mcode nm clt)] }
1337 | TCircles
1338 { [Ast0.Ecircles(clt2mcode "ooo" $1,None)] }
1339 | TCircles TWhen TNotEq eexpr TLineEnd
1340 { [Ast0.Ecircles(clt2mcode "ooo" $1,Some $4)] }
1341 | dexpr TComma eexpr_list_circles
1342 { $1::Ast0.EComma(clt2mcode "," $2)::$3 }
1343 | TMetaExpList TComma eexpr_list_circles
1344 { let (nm,clt) = $1 in
1345 Ast0.MetaExprList(clt2mcode nm clt)::Ast0.EComma(clt2mcode "," $2)::$3 }
1346 | TCircles TComma eexpr_list_circles
1347 { Ast0.Ecircles(clt2mcode "ooo" $1,None)::
1348 Ast0.EComma(clt2mcode "," $2)::$3 }
1349 | TCircles TWhen TNotEq eexpr TLineEnd TComma eexpr_list_circles
1350 { Ast0.Ecircles(clt2mcode "ooo" $1,Some $4)::
1351 Ast0.EComma(clt2mcode "," $6)::$7 }
1352
1353 eexpr_list_stars:
1354 dexpr
1355 { [$1] }
1356 | TMetaExpList
1357 { let (nm,clt) = $1 in [Ast0.MetaExprList(clt2mcode nm clt)] }
1358 | TStars
1359 { [Ast0.Estars(clt2mcode "***" $1,None)] }
1360 | TStars TWhen TNotEq eexpr TLineEnd
1361 { [Ast0.Estars(clt2mcode "***" $1,Some $4)] }
1362 | dexpr TComma eexpr_list_stars
1363 { $1::Ast0.EComma(clt2mcode "," $2)::$3 }
1364 | TMetaExpList TComma eexpr_list_stars
1365 { let (nm,clt) = $1 in
1366 Ast0.MetaExprList(clt2mcode nm clt)::Ast0.EComma(clt2mcode "," $2)::$3 }
1367 | TStars TComma eexpr_list_stars
1368 { Ast0.Estars(clt2mcode "***" $1,None)::
1369 Ast0.EComma(clt2mcode "," $2)::$3 }
1370 | TStars TWhen TNotEq eexpr TLineEnd TComma eexpr_list_stars
1371 { Ast0.Estars(clt2mcode "***" $1,Some $4)::
1372 Ast0.EComma(clt2mcode "," $6)::$7 }
1373
1374 eexpr_list_opt: eexpr_list { $1 }
1375 | /* empty */ { Ast0.DOTS([]) }
1376
1377 expr_mid:
1378 expr { [$1] }
1379 | expr TMid0 expr_mid { $1::$3 }
1380
1381 eexpr_mid:
1382 eexpr { [$1] }
1383 | eexpr TMid0 eexpr_mid { $1::$3 }
1384
1385 eexpr_opt: eexpr { Some ($1) }
1386 | /* empty */ { None }
1387