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