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