Release coccinelle-0.2.3rc1
[bpt/coccinelle.git] / parsing_cocci / parser_cocci_menhir.mly
CommitLineData
9f8e26f4 1/*
ae4735db 2 * Copyright 2005-2010, Ecole des Mines de Nantes, University of Copenhagen
9f8e26f4
C
3 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
4 * This file is part of Coccinelle.
5 *
6 * Coccinelle is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, according to version 2 of the License.
9 *
10 * Coccinelle is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * The authors reserve the right to distribute this or future versions of
19 * Coccinelle under other licenses.
20 */
21
22
5636bb2c
C
23/*
24 * Copyright 2005-2010, Ecole des Mines de Nantes, University of Copenhagen
25 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
26 * This file is part of Coccinelle.
27 *
28 * Coccinelle is free software: you can redistribute it and/or modify
29 * it under the terms of the GNU General Public License as published by
30 * the Free Software Foundation, according to version 2 of the License.
31 *
32 * Coccinelle is distributed in the hope that it will be useful,
33 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU General Public License for more details.
36 *
37 * You should have received a copy of the GNU General Public License
38 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
39 *
40 * The authors reserve the right to distribute this or future versions of
41 * Coccinelle under other licenses.
42 */
43
44
34e49164
C
45%{
46
47(* Not clear how to allow function declarations to specify a return type
48and how to allow both to be specified as static, because they are in
49different rules. The rules seem to have to be combined, which would allow
50functions to be declared as local variables *)
51
52(* Not clear how to let a function have a parameter of type void. At the
53moment, void is allowed to be the type of a variable, which is wrong, and a
54parameter needs both a type and an identifier *)
55module Ast0 = Ast0_cocci
56module Ast = Ast_cocci
57module P = Parse_aux
58%}
59
60%token EOF
61
62%token TIdentifier TExpression TStatement TFunction TLocal TType TParameter
113803cf 63%token TIdExpression TInitialiser
34e49164 64%token Tlist TFresh TConstant TError TWords TWhy0 TPlus0 TBang0
faf9a90c 65%token TPure TContext TGenerated
34e49164 66%token TTypedef TDeclarer TIterator TName TPosition TPosAny
faf9a90c 67%token TUsing TDisable TExtends TDepends TOn TEver TNever TExists TForall
951c7801 68%token TScript TInitialize TFinalize TNothing TVirtual
34e49164
C
69%token<string> TRuleName
70
71%token<Data.clt> Tchar Tshort Tint Tdouble Tfloat Tlong
faf9a90c 72%token<Data.clt> Tvoid Tstruct Tunion Tenum
34e49164
C
73%token<Data.clt> Tunsigned Tsigned
74
75%token<Data.clt> Tstatic Tauto Tregister Textern Tinline Ttypedef
76%token<Data.clt> Tconst Tvolatile
77%token<string * Data.clt> Tattr
78
79%token <Data.clt> TIf TElse TWhile TFor TDo TSwitch TCase TDefault TReturn
80%token <Data.clt> TBreak TContinue TGoto TSizeof TFunDecl
c3e37e97
C
81%token <string * Data.clt> TIdent TTypeId TDeclarerId TIteratorId
82%token <Ast_cocci.added_string * Data.clt> TPragma
34e49164 83
951c7801
C
84%token <Parse_aux.idinfo> TMetaId TMetaFunc TMetaLocalFunc
85%token <Parse_aux.idinfo> TMetaIterator TMetaDeclarer
86%token <Parse_aux.expinfo> TMetaErr
87%token <Parse_aux.info> TMetaParam TMetaStm TMetaStmList TMetaType
88%token <Parse_aux.info> TMetaInit
89%token <Parse_aux.list_info> TMetaParamList TMetaExpList
90%token <Parse_aux.typed_expinfo> TMetaExp TMetaIdExp TMetaLocalIdExp TMetaConst
91%token <Parse_aux.pos_info> TMetaPos
34e49164
C
92
93%token TArob TArobArob TPArob
94%token <string> TScriptData
95
96%token <Data.clt> TEllipsis TOEllipsis TCEllipsis TPOEllipsis TPCEllipsis
1be43e12 97%token <Data.clt> TWhen TWhenTrue TWhenFalse TAny TStrict TLineEnd
34e49164
C
98
99%token <Data.clt> TWhy TDotDot TBang TOPar TOPar0
100%token <Data.clt> TMid0 TCPar TCPar0
101
0708f913 102%token <string> TPathIsoFile
34e49164
C
103%token <string * Data.clt> TIncludeL TIncludeNL
104%token <Data.clt * token> TDefine
708f4980 105%token <Data.clt * token * int * int> TDefineParam
34e49164
C
106%token <string * Data.clt> TMinusFile TPlusFile
107
108%token <Data.clt> TInc TDec
109
110%token <string * Data.clt> TString TChar TFloat TInt
111
112%token <Data.clt> TOrLog
113%token <Data.clt> TAndLog
114%token <Data.clt> TOr
115%token <Data.clt> TXor
faf9a90c 116%token <Data.clt> TAnd
5636bb2c 117%token <Data.clt> TEqEq TNotEq TTildeEq TTildeExclEq TSub
34e49164
C
118%token <Ast_cocci.logicalOp * Data.clt> TLogOp /* TInf TSup TInfEq TSupEq */
119%token <Ast_cocci.arithOp * Data.clt> TShOp /* TShl TShr */
120%token <Ast_cocci.arithOp * Data.clt> TDmOp /* TDiv TMod */
121%token <Data.clt> TPlus TMinus
122%token <Data.clt> TMul TTilde
123
1be43e12 124%token <Data.clt> TOBrace TCBrace TOInit
34e49164
C
125%token <Data.clt> TOCro TCCro
126
127%token <Data.clt> TPtrOp
128
978fd7e5 129%token TMPtVirg TCppConcatOp
34e49164
C
130%token <Data.clt> TEq TDot TComma TPtVirg
131%token <Ast_cocci.assignOp * Data.clt> TAssign
132
133%token TIso TRightIso TIsoExpression TIsoStatement TIsoDeclaration TIsoType
c3e37e97 134%token TIsoTopLevel TIsoArgExpression TIsoTestExpression TIsoToTestExpression
34e49164
C
135
136%token TInvalid
137
138/* operator precedence */
139%nonassoc TIf
140%nonassoc TElse
141
142%left TOrLog
143%left TAndLog
144%left TOr
145%left TXor
faf9a90c 146%left TAnd
34e49164
C
147%left TEqEq TNotEq
148%left TLogOp /* TInf TSup TInfEq TSupEq */
149%left TShOp /* TShl TShr */
150%left TPlus TMinus
151%left TMul TDmOp /* TDiv TMod */
152
153%start reinit
154%type <unit> reinit
155
156%start minus_main
157%type <Ast0_cocci.rule> minus_main
158
159%start minus_exp_main
160%type <Ast0_cocci.rule> minus_exp_main
161
162%start plus_main
163%type <Ast0_cocci.rule> plus_main
164
165%start plus_exp_main
166%type <Ast0_cocci.rule> plus_exp_main
167
168%start include_main
978fd7e5 169%type <Data.incl_iso list> include_main
34e49164
C
170
171%start iso_rule_name
172%type <Ast_cocci.rulename>
173iso_rule_name
174
175%start rule_name
176%type <Ast_cocci.rulename>
177rule_name
178
179%start meta_main
180%type <(Ast_cocci.metavar,Ast_cocci.metavar) Common.either list> meta_main
181
ae4735db 182%start <string * Ast_cocci.meta_name> script_meta_main
34e49164
C
183
184%start iso_main
185%type <Ast0_cocci.anything list list> iso_main
186
187%start iso_meta_main
188%type <(Ast_cocci.metavar,Ast_cocci.metavar) Common.either list> iso_meta_main
189
190%start never_used
191%type <unit> never_used
192
193%%
194
195reinit: { }
196minus_main: minus_body EOF { $1 } | m=minus_body TArobArob { m }
197| m=minus_body TArob { m }
198plus_main: plus_body EOF { $1 } | p=plus_body TArobArob { p }
199| p=plus_body TArob { p }
200minus_exp_main: minus_exp_body EOF { $1 } | m=minus_exp_body TArobArob { m }
201| m=minus_exp_body TArob { m }
202plus_exp_main: plus_exp_body EOF { $1 } | p=plus_exp_body TArobArob { p }
203| p=plus_exp_body TArob { p }
204meta_main: m=metadec { m (!Ast0.rule_name) }
205iso_meta_main: m=metadec { m "" }
206
207/*****************************************************************************
208*
209*
210*****************************************************************************/
211
212pure:
213 TPure { Ast0.Pure }
214| TContext { Ast0.Context }
215| TPure TContext { Ast0.PureContext }
216| TContext TPure { Ast0.PureContext }
217| /* empty */ { Ast0.Impure }
218
219iso_rule_name:
220 nm=pure_ident TArob { P.make_iso_rule_name_result (P.id2name nm) }
221
222rule_name:
223 nm=ioption(pure_ident) extends d=depends i=loption(choose_iso)
224 a=loption(disable) e=exists ee=is_expression TArob
225 { P.make_cocci_rule_name_result nm d i a e ee }
faf9a90c
C
226 | TGenerated extends d=depends i=loption(choose_iso)
227 a=loption(disable) e=exists ee=is_expression TArob
228 /* these rules have no name as a cheap way to ensure that no normal
229 rule inherits their metavariables or depends on them */
230 { P.make_generated_rule_name_result None d i a e ee }
1be43e12
C
231 | TScript TDotDot lang=pure_ident d=depends TArob
232 { P.make_script_rule_name_result lang d }
c3e37e97
C
233 | TInitialize TDotDot lang=pure_ident d=depends TArob
234 { P.make_initial_script_rule_name_result lang d }
235 | TFinalize TDotDot lang=pure_ident d=depends TArob
236 { P.make_final_script_rule_name_result lang d }
34e49164
C
237
238extends:
239 /* empty */ { () }
240| TExtends parent=TRuleName
241 { !Data.install_bindings (parent) }
242
243depends:
244 /* empty */ { Ast.NoDep }
245| TDepends TOn parents=dep { parents }
246
247dep:
248 pnrule { $1 }
249| dep TAndLog dep { Ast.AndDep($1, $3) }
250| dep TOrLog dep { Ast.OrDep ($1, $3) }
251
252pnrule:
253 TRuleName { Ast.Dep $1 }
254| TBang TRuleName { Ast.AntiDep $2 }
255| TEver TRuleName { Ast.EverDep $2 }
256| TNever TRuleName { Ast.NeverDep $2 }
257| TOPar dep TCPar { $2 }
258
259choose_iso:
260 TUsing separated_nonempty_list(TComma,TString) { List.map P.id2name $2 }
261
262disable:
263 TDisable separated_nonempty_list(TComma,pure_ident) { List.map P.id2name $2 }
264
265exists:
266 TExists { Ast.Exists }
267| TForall { Ast.Forall }
34e49164
C
268| { Ast.Undetermined }
269
270is_expression: // for more flexible parsing of top level expressions
271 { false }
272| TExpression { true }
273
274include_main:
275 list(incl) TArob { $1 }
276| list(incl) TArobArob { $1 }
277
278incl:
978fd7e5
C
279 TIncludeL { let (x,_) = $1 in Data.Include(x) }
280| TUsing TString { Data.Iso(Common.Left(P.id2name $2)) }
281| TUsing TPathIsoFile { Data.Iso(Common.Right $2) }
951c7801
C
282| TVirtual comma_list(pure_ident)
283 { let names = List.map P.id2name $2 in
284 (* ensure that the names of virtual and real rules don't overlap *)
285 List.iter
286 (function name -> Hashtbl.add Data.all_metadecls name [])
287 names;
288 Data.Virt(names) }
34e49164
C
289
290metadec:
291 ar=arity ispure=pure
292 kindfn=metakind ids=comma_list(pure_ident_or_meta_ident) TMPtVirg
293 { P.create_metadec ar ispure kindfn ids }
b1b2de81
C
294| kindfn=metakind_fresh ids=comma_list(pure_ident_or_meta_ident_with_seed)
295 TMPtVirg
296 { P.create_fresh_metadec kindfn ids }
ae4735db
C
297| ar=arity ispure=pure
298 kindfn=metakind_atomic_maybe_virt
299 ids=
300 comma_list(pure_ident_or_meta_ident_with_idconstraint_virt(re_or_not_eqid))
301 TMPtVirg
302 { let (normal,virt) = Common.partition_either (fun x -> x) ids in
303 let (idfn,virtfn) = kindfn in
304 function cr ->
305 (P.create_metadec_with_constraints ar ispure idfn normal cr) @
306 (P.create_metadec_virt ar ispure virtfn virt cr) }
34e49164
C
307| ar=arity ispure=pure
308 kindfn=metakind_atomic
7f004419
C
309 ids=comma_list(pure_ident_or_meta_ident_with_idconstraint(re_or_not_eqid))
310 TMPtVirg
951c7801 311 { P.create_metadec_with_constraints ar ispure kindfn ids }
34e49164
C
312| ar=arity ispure=pure
313 kindfn=metakind_atomic_expi
5636bb2c 314 ids=comma_list(pure_ident_or_meta_ident_with_econstraint(re_or_not_eqe_or_sub))
7f004419 315 TMPtVirg
951c7801 316 { P.create_metadec_with_constraints ar ispure kindfn ids }
34e49164
C
317| ar=arity ispure=pure
318 kindfn=metakind_atomic_expe
5636bb2c
C
319 ids=comma_list(pure_ident_or_meta_ident_with_econstraint(not_ceq_or_sub))
320 TMPtVirg
951c7801 321 { P.create_metadec_with_constraints ar ispure kindfn ids }
34e49164 322| ar=arity TPosition a=option(TPosAny)
951c7801 323 ids=comma_list(pure_ident_or_meta_ident_with_x_eq(not_pos)) TMPtVirg
faf9a90c
C
324 (* pb: position variables can't be inherited from normal rules, and then
325 there is no way to inherit from a generated rule, so there is no point
326 to have a position variable *)
327 { (if !Data.in_generating
328 then failwith "position variables not allowed in a generated rule file");
329 let kindfn arity name pure check_meta constraints =
34e49164
C
330 let tok = check_meta(Ast.MetaPosDecl(arity,name)) in
331 let any = match a with None -> Ast.PER | Some _ -> Ast.ALL in
332 !Data.add_pos_meta name constraints any; tok in
951c7801 333 P.create_metadec_with_constraints ar false kindfn ids }
34e49164
C
334| ar=arity ispure=pure
335 TParameter Tlist TOCro id=pure_ident_or_meta_ident TCCro
336 ids=comma_list(pure_ident_or_meta_ident) TMPtVirg
337 { P.create_len_metadec ar ispure
338 (fun lenname arity name pure check_meta ->
339 let tok =
340 check_meta(Ast.MetaParamListDecl(arity,name,Some lenname)) in
341 !Data.add_paramlist_meta name (Some lenname) pure; tok)
342 id ids }
343| ar=arity ispure=pure
344 TExpression Tlist TOCro id=pure_ident_or_meta_ident TCCro
345 ids=comma_list(pure_ident_or_meta_ident) TMPtVirg
346 { P.create_len_metadec ar ispure
347 (fun lenname arity name pure check_meta ->
348 let tok =
349 check_meta(Ast.MetaExpListDecl(arity,name,Some lenname)) in
350 !Data.add_explist_meta name (Some lenname) pure; tok)
351 id ids }
352
b1b2de81 353%inline metakind_fresh:
34e49164 354 TFresh TIdentifier
b1b2de81
C
355 { (fun name check_meta seed ->
356 let tok = check_meta(Ast.MetaFreshIdDecl(name,seed)) in
357 !Data.add_fresh_id_meta name; tok) }
358
ae4735db 359/* metavariable kinds with no constraints, etc */
b1b2de81
C
360%inline metakind:
361 TParameter
34e49164
C
362 { (fun arity name pure check_meta ->
363 let tok = check_meta(Ast.MetaParamDecl(arity,name)) in
364 !Data.add_param_meta name pure; tok) }
365| TParameter Tlist
366 { (fun arity name pure check_meta ->
367 let tok = check_meta(Ast.MetaParamListDecl(arity,name,None)) in
368 !Data.add_paramlist_meta name None pure; tok) }
369| TExpression Tlist
370 { (fun arity name pure check_meta ->
371 let tok = check_meta(Ast.MetaExpListDecl(arity,name,None)) in
372 !Data.add_explist_meta name None pure; tok) }
373| TType
374 { (fun arity name pure check_meta ->
375 let tok = check_meta(Ast.MetaTypeDecl(arity,name)) in
faf9a90c 376 !Data.add_type_meta name pure; tok) }
113803cf
C
377| TInitialiser
378 { (fun arity name pure check_meta ->
379 let tok = check_meta(Ast.MetaInitDecl(arity,name)) in
380 !Data.add_init_meta name pure; tok) }
34e49164
C
381| TStatement
382 { (fun arity name pure check_meta ->
383 let tok = check_meta(Ast.MetaStmDecl(arity,name)) in
384 !Data.add_stm_meta name pure; tok) }
385| TStatement Tlist
386 { (fun arity name pure check_meta ->
387 let tok = check_meta(Ast.MetaStmListDecl(arity,name)) in
388 !Data.add_stmlist_meta name pure; tok) }
389| TTypedef
390 { (fun arity (_,name) pure check_meta ->
391 if arity = Ast.NONE && pure = Ast0.Impure
392 then (!Data.add_type_name name; [])
393 else raise (Semantic_cocci.Semantic "bad typedef")) }
394| TDeclarer TName
395 { (fun arity (_,name) pure check_meta ->
396 if arity = Ast.NONE && pure = Ast0.Impure
397 then (!Data.add_declarer_name name; [])
398 else raise (Semantic_cocci.Semantic "bad declarer")) }
399| TIterator TName
400 { (fun arity (_,name) pure check_meta ->
401 if arity = Ast.NONE && pure = Ast0.Impure
402 then (!Data.add_iterator_name name; [])
403 else raise (Semantic_cocci.Semantic "bad iterator")) }
404
ae4735db 405%inline metakind_atomic_maybe_virt:
34e49164 406 TIdentifier
ae4735db
C
407 {
408 let idfn arity name pure check_meta constraints =
409 let tok = check_meta(Ast.MetaIdDecl(arity,name)) in
410 !Data.add_id_meta name constraints pure; tok in
411 let virtfn arity name pure check_meta virtual_env =
412 try
413 let vl = List.assoc name virtual_env in
414 !Data.add_virt_id_meta_found name vl; []
415 with Not_found ->
416 let name = ("virtual",name) in
417 let tok = check_meta(Ast.MetaIdDecl(arity,name)) in
418 !Data.add_virt_id_meta_not_found name pure; tok in
419 (idfn,virtfn) }
420
421%inline metakind_atomic:
422 TFunction
34e49164
C
423 { (fun arity name pure check_meta constraints ->
424 let tok = check_meta(Ast.MetaFuncDecl(arity,name)) in
425 !Data.add_func_meta name constraints pure; tok) }
426| TLocal TFunction
427 { (fun arity name pure check_meta constraints ->
428 let tok = check_meta(Ast.MetaLocalFuncDecl(arity,name)) in
429 !Data.add_local_func_meta name constraints pure;
430 tok) }
431| TDeclarer
432 { (fun arity name pure check_meta constraints ->
433 let tok = check_meta(Ast.MetaDeclarerDecl(arity,name)) in
434 !Data.add_declarer_meta name constraints pure; tok) }
435| TIterator
436 { (fun arity name pure check_meta constraints ->
437 let tok = check_meta(Ast.MetaIteratorDecl(arity,name)) in
438 !Data.add_iterator_meta name constraints pure; tok) }
439
440%inline metakind_atomic_expi:
441 TError
442 { (fun arity name pure check_meta constraints ->
443 let tok = check_meta(Ast.MetaErrDecl(arity,name)) in
444 !Data.add_err_meta name constraints pure; tok) }
445| l=option(TLocal) TIdExpression ty=ioption(meta_exp_type)
446 { (fun arity name pure check_meta constraints ->
447 match l with
448 None ->
449 !Data.add_idexp_meta ty name constraints pure;
450 check_meta(Ast.MetaIdExpDecl(arity,name,ty))
451 | Some _ ->
452 !Data.add_local_idexp_meta ty name constraints pure;
453 check_meta(Ast.MetaLocalIdExpDecl(arity,name,ty))) }
454| l=option(TLocal) TIdExpression m=nonempty_list(TMul)
455 { (fun arity name pure check_meta constraints ->
456 let ty = Some [P.ty_pointerify Type_cocci.Unknown m] in
457 match l with
458 None ->
459 !Data.add_idexp_meta ty name constraints pure;
460 check_meta(Ast.MetaIdExpDecl(arity,name,ty))
461 | Some _ ->
462 !Data.add_local_idexp_meta ty name constraints pure;
463 check_meta(Ast.MetaLocalIdExpDecl(arity,name,ty))) }
464| TExpression m=nonempty_list(TMul)
465 { (fun arity name pure check_meta constraints ->
466 let ty = Some [P.ty_pointerify Type_cocci.Unknown m] in
467 let tok = check_meta(Ast.MetaExpDecl(arity,name,ty)) in
468 !Data.add_exp_meta ty name constraints pure; tok) }
469| vl=meta_exp_type TOCro TCCro
470 { (fun arity name pure check_meta constraints ->
471 let ty = Some (List.map (function x -> Type_cocci.Array x) vl) in
472 let tok = check_meta(Ast.MetaExpDecl(arity,name,ty)) in
473 !Data.add_exp_meta ty name constraints pure; tok) }
474| TConstant ty=ioption(meta_exp_type)
475 { (fun arity name pure check_meta constraints ->
476 let tok = check_meta(Ast.MetaConstDecl(arity,name,ty)) in
477 !Data.add_const_meta ty name constraints pure; tok) }
478
479%inline metakind_atomic_expe:
480 TExpression
481 { (fun arity name pure check_meta constraints ->
482 let tok = check_meta(Ast.MetaExpDecl(arity,name,None)) in
5636bb2c 483 !Data.add_exp_meta None name constraints pure; tok) }
34e49164
C
484| vl=meta_exp_type // no error if use $1 but doesn't type check
485 { (fun arity name pure check_meta constraints ->
486 let ty = Some vl in
5636bb2c
C
487 (match constraints with
488 Ast0.NotExpCstrt constraints ->
489 List.iter
490 (function c ->
491 match Ast0.unwrap c with
492 Ast0.Constant(_) ->
493 if not
494 (List.exists
495 (function
496 Type_cocci.BaseType(Type_cocci.IntType) -> true
497 | Type_cocci.BaseType(Type_cocci.ShortType) -> true
498 | Type_cocci.BaseType(Type_cocci.LongType) -> true
499 | _ -> false)
500 vl)
501 then
502 failwith "metavariable with int constraint must be an int"
503 | _ -> ())
504 constraints
505 | _ -> ());
34e49164 506 let tok = check_meta(Ast.MetaExpDecl(arity,name,ty)) in
5636bb2c 507 !Data.add_exp_meta ty name constraints pure; tok)
951c7801 508 }
34e49164
C
509
510
511meta_exp_type:
978fd7e5 512 t=typedef_ctype
34e49164
C
513 { [Ast0_cocci.ast0_type_to_type t] }
514| TOBrace t=comma_list(ctype) TCBrace m=list(TMul)
515 { List.map
516 (function x -> P.ty_pointerify (Ast0_cocci.ast0_type_to_type x) m)
517 t }
518
519arity: TBang0 { Ast.UNIQUE }
520 | TWhy0 { Ast.OPT }
521 | TPlus0 { Ast.MULTI }
522 | /* empty */ { Ast.NONE }
523
978fd7e5
C
524/* ---------------------------------------------------------------------- */
525
526%inline
527signable_types:
528 ty=Tchar
529 { Ast0.wrap(Ast0.BaseType(Ast.CharType,[P.clt2mcode "char" ty])) }
530| ty=Tshort
531 { Ast0.wrap(Ast0.BaseType(Ast.ShortType,[P.clt2mcode "short" ty])) }
532| ty=Tint
533 { Ast0.wrap(Ast0.BaseType(Ast.IntType,[P.clt2mcode "int" ty])) }
534| p=TMetaType
535 { let (nm,pure,clt) = p in
536 Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure)) }
537| r=TRuleName TDot p=TIdent
538 { let nm = (r,P.id2name p) in
539 (* this is only possible when we are in a metavar decl. Otherwise,
540 it will be represented already as a MetaType *)
541 let _ = P.check_meta(Ast.MetaTypeDecl(Ast.NONE,nm)) in
542 Ast0.wrap(Ast0.MetaType(P.clt2mcode nm (P.id2clt p),
543 Ast0.Impure (*will be ignored*))) }
544| ty=Tlong
545 { Ast0.wrap(Ast0.BaseType(Ast.LongType,[P.clt2mcode "long" ty])) }
546| ty1=Tlong ty2=Tlong
547 { Ast0.wrap
548 (Ast0.BaseType
549 (Ast.LongLongType,
550 [P.clt2mcode "long" ty1;P.clt2mcode "long" ty2])) }
551
552%inline
553non_signable_types:
554 ty=Tvoid
555 { Ast0.wrap(Ast0.BaseType(Ast.VoidType,[P.clt2mcode "void" ty])) }
556| ty=Tdouble
557 { Ast0.wrap(Ast0.BaseType(Ast.DoubleType,[P.clt2mcode "double" ty])) }
558| ty=Tfloat
559 { Ast0.wrap(Ast0.BaseType(Ast.FloatType,[P.clt2mcode "float" ty])) }
560| s=Tenum i=ident
561 { Ast0.wrap(Ast0.EnumName(P.clt2mcode "enum" s, i)) }
562| s=struct_or_union i=ident
563 { Ast0.wrap(Ast0.StructUnionName(s, Some i)) }
564| s=struct_or_union i=ioption(ident)
565 l=TOBrace d=struct_decl_list r=TCBrace
566 { (if i = None && !Data.in_iso
567 then failwith "structures must be named in the iso file");
568 Ast0.wrap(Ast0.StructUnionDef(Ast0.wrap(Ast0.StructUnionName(s, i)),
569 P.clt2mcode "{" l,
570 d, P.clt2mcode "}" r)) }
571| s=TMetaType l=TOBrace d=struct_decl_list r=TCBrace
572 { let (nm,pure,clt) = s in
573 let ty = Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure)) in
574 Ast0.wrap(Ast0.StructUnionDef(ty,P.clt2mcode "{" l,d,P.clt2mcode "}" r)) }
575| p=TTypeId
576 { Ast0.wrap(Ast0.TypeName(P.id2mcode p)) }
577
578%inline
579all_basic_types:
580 r=Tsigned ty=signable_types
581 { Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Signed r,Some ty)) }
582| r=Tunsigned ty=signable_types
583 { Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Unsigned r,Some ty)) }
584| ty=signable_types { ty }
585| ty=non_signable_types { ty }
586
587ctype:
588 cv=ioption(const_vol) ty=all_basic_types m=list(TMul)
589 { P.pointerify (P.make_cv cv ty) m }
590| r=Tsigned
591 { Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Signed r,None)) }
592| r=Tunsigned
593 { Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Unsigned r,None)) }
594| lp=TOPar0 t=midzero_list(ctype,ctype) rp=TCPar0
595 { let (mids,code) = t in
596 Ast0.wrap
597 (Ast0.DisjType(P.clt2mcode "(" lp,code,mids, P.clt2mcode ")" rp)) }
598
599/* signed, unsigned alone not allowed */
600typedef_ctype:
601 cv=ioption(const_vol) ty=all_basic_types m=list(TMul)
602 { P.pointerify (P.make_cv cv ty) m }
603| lp=TOPar0 t=midzero_list(ctype,ctype) rp=TCPar0
604 { let (mids,code) = t in
605 Ast0.wrap
606 (Ast0.DisjType(P.clt2mcode "(" lp,code,mids, P.clt2mcode ")" rp)) }
607
608/* ---------------------------------------------------------------------- */
34e49164
C
609
610struct_or_union:
611 s=Tstruct { P.clt2mcode Ast.Struct s }
612 | u=Tunion { P.clt2mcode Ast.Union u }
613
614struct_decl:
615 TNothing { [] }
616 | t=ctype d=d_ident pv=TPtVirg
617 { let (id,fn) = d in
618 [Ast0.wrap(Ast0.UnInit(None,fn t,id,P.clt2mcode ";" pv))] }
978fd7e5 619 | t=ctype lp1=TOPar st=TMul d=d_ident rp1=TCPar
34e49164
C
620 lp2=TOPar p=decl_list(name_opt_decl) rp2=TCPar pv=TPtVirg
621 { let (id,fn) = d in
622 let t =
623 Ast0.wrap
624 (Ast0.FunctionPointer
625 (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
626 P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
627 [Ast0.wrap(Ast0.UnInit(None,fn t,id,P.clt2mcode ";" pv))] }
628 | cv=ioption(const_vol) i=pure_ident d=d_ident pv=TPtVirg
629 { let (id,fn) = d in
630 let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
631 [Ast0.wrap(Ast0.UnInit(None,fn idtype,id,P.clt2mcode ";" pv))] }
632
633struct_decl_list:
634 struct_decl_list_start { Ast0.wrap(Ast0.DOTS($1)) }
635
636struct_decl_list_start:
637 struct_decl { $1 }
638| struct_decl struct_decl_list_start { $1@$2 }
639| d=edots_when(TEllipsis,struct_decl) r=continue_struct_decl_list
640 { (P.mkddots "..." d)::r }
641
642continue_struct_decl_list:
643 /* empty */ { [] }
644| struct_decl struct_decl_list_start { $1@$2 }
645| struct_decl { $1 }
646
34e49164
C
647
648/*****************************************************************************/
649
650/* have to inline everything to avoid conflicts? switch to proper
651declarations, statements, and expressions for the subterms */
652
faf9a90c 653minus_body:
34e49164
C
654 f=loption(filespec)
655 b=loption(minus_start)
978fd7e5
C
656 /*ew=loption(error_words)*/
657 { match f@b(*@ew*) with
34e49164
C
658 [] -> raise (Semantic_cocci.Semantic "minus slice can't be empty")
659 | code -> Top_level.top_level code }
660
faf9a90c 661plus_body:
34e49164
C
662 f=loption(filespec)
663 b=loption(plus_start)
978fd7e5
C
664 /*ew=loption(error_words)*/
665 { Top_level.top_level (f@b(*@ew*)) }
34e49164
C
666
667minus_exp_body:
668 f=loption(filespec)
669 b=top_eexpr
978fd7e5
C
670 /*ew=loption(error_words)*/
671 { match f@[b](*@ew*) with
34e49164
C
672 [] -> raise (Semantic_cocci.Semantic "minus slice can't be empty")
673 | code -> Top_level.top_level code }
674
675plus_exp_body:
676 f=loption(filespec)
677 b=top_eexpr
978fd7e5
C
678 /*ew=loption(error_words)*/
679 { Top_level.top_level (f@[b](*@ew*)) }
34e49164
C
680
681filespec:
682 TMinusFile TPlusFile
683 { [Ast0.wrap
684 (Ast0.FILEINFO(P.id2mcode $1,
685 P.id2mcode $2))] }
686
687includes:
688 TIncludeL
689 { Ast0.wrap
7f004419
C
690 (Ast0.Include(P.clt2mcode "#include"
691 (P.drop_pos (P.drop_aft (P.id2clt $1))),
34e49164
C
692 let (arity,ln,lln,offset,col,strbef,straft,pos) =
693 P.id2clt $1 in
694 let clt =
695 (arity,ln,lln,offset,0,strbef,straft,pos) in
696 P.clt2mcode
697 (Ast.Local (Parse_aux.str2inc (P.id2name $1)))
698 (P.drop_bef clt))) }
699| TIncludeNL
700 { Ast0.wrap
7f004419
C
701 (Ast0.Include(P.clt2mcode "#include"
702 (P.drop_pos (P.drop_aft (P.id2clt $1))),
34e49164
C
703 let (arity,ln,lln,offset,col,strbef,straft,pos) =
704 P.id2clt $1 in
705 let clt =
706 (arity,ln,lln,offset,0,strbef,straft,pos) in
707 P.clt2mcode
708 (Ast.NonLocal (Parse_aux.str2inc (P.id2name $1)))
709 (P.drop_bef clt))) }
5636bb2c
C
710| d=defineop TLineEnd
711 { d (Ast0.wrap(Ast0.DOTS([]))) }
34e49164
C
712| d=defineop t=ctype TLineEnd
713 { let ty = Ast0.wrap(Ast0.TopExp(Ast0.wrap(Ast0.TypeExp(t)))) in
714 d (Ast0.wrap(Ast0.DOTS([ty]))) }
715| defineop b=toplevel_seq_start(toplevel_after_dots) TLineEnd
716 { let body =
717 match b with
718 [e] ->
719 (match Ast0.unwrap e with
720 Ast0.Exp(e1) ->
721 [Ast0.rewrap e (Ast0.TopExp(Ast0.set_arg_exp (e1)))]
722 | _ -> b)
723 | _ -> b in
724 $1 (Ast0.wrap(Ast0.DOTS(body))) }
725
726defineop:
727 TDefine
728 { let (clt,ident) = $1 in
729 function body ->
730 Ast0.wrap
731 (Ast0.Define
732 (P.clt2mcode "#define" clt,
733 (match ident with
734 TMetaId((nm,constraints,pure,clt)) ->
735 Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure))
736 | TIdent(nm_pure) ->
737 Ast0.wrap(Ast0.Id(P.id2mcode nm_pure))
738 | _ ->
739 raise
740 (Semantic_cocci.Semantic
741 "unexpected name for a #define")),
742 Ast0.wrap Ast0.NoParams,
743 body)) }
744| TDefineParam define_param_list_option TCPar
708f4980
C
745 { let (clt,ident,parenoff,parencol) = $1 in
746 (* clt is the start of the #define itself *)
34e49164
C
747 let (arity,line,lline,offset,col,strbef,straft,pos) = clt in
748 let lp =
0708f913 749 P.clt2mcode "("
708f4980 750 (arity,line,lline,parenoff,parencol,[],[],Ast0.NoMetaPos) in
34e49164
C
751 function body ->
752 Ast0.wrap
753 (Ast0.Define
754 (P.clt2mcode "#define" clt,
755 (match ident with
756 TMetaId((nm,constraints,pure,clt)) ->
757 Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure))
758 | TIdent(nm_pure) ->
759 Ast0.wrap(Ast0.Id(P.id2mcode nm_pure))
760 | _ ->
761 raise
762 (Semantic_cocci.Semantic
763 "unexpected name for a #define")),
764 Ast0.wrap (Ast0.DParams (lp,$2,P.clt2mcode ")" $3)),body)) }
765
766/* ---------------------------------------------------------------------- */
767
768define_param_list: define_param_list_start
769 {let circle x =
770 match Ast0.unwrap x with Ast0.DPcircles(_) -> true | _ -> false in
771 if List.exists circle $1
772 then Ast0.wrap(Ast0.CIRCLES($1))
773 else Ast0.wrap(Ast0.DOTS($1)) }
774
775define_param_list_start:
776 ident { [Ast0.wrap(Ast0.DParam $1)] }
777 | ident TComma define_param_list_start
778 { Ast0.wrap(Ast0.DParam $1)::
779 Ast0.wrap(Ast0.DPComma(P.clt2mcode "," $2))::$3 }
780 | d=TEllipsis r=list(dp_comma_args(TEllipsis))
781 { (P.mkdpdots "..." d)::
782 (List.concat (List.map (function x -> x (P.mkdpdots "...")) r)) }
783
784dp_comma_args(dotter):
785 c=TComma d=dotter
786 { function dot_builder ->
787 [Ast0.wrap(Ast0.DPComma(P.clt2mcode "," c)); dot_builder d] }
788| TComma ident
789 { function dot_builder ->
790 [Ast0.wrap(Ast0.DPComma(P.clt2mcode "," $1));
791 Ast0.wrap(Ast0.DParam $2)] }
792
793define_param_list_option: define_param_list { $1 }
794 | /* empty */ { Ast0.wrap(Ast0.DOTS([])) }
795
796/*****************************************************************************/
797
798funproto:
799 s=ioption(storage) t=ctype
800 id=func_ident lp=TOPar d=decl_list(name_opt_decl) rp=TCPar pt=TPtVirg
801 { Ast0.wrap
802 (Ast0.UnInit
803 (s,
804 Ast0.wrap
805 (Ast0.FunctionType(Some t,
806 P.clt2mcode "(" lp, d, P.clt2mcode ")" rp)),
807 id, P.clt2mcode ";" pt)) }
34e49164
C
808
809fundecl:
810 f=fninfo
811 TFunDecl i=func_ident lp=TOPar d=decl_list(decl) rp=TCPar
812 lb=TOBrace b=fun_start rb=TCBrace
978fd7e5
C
813 { P.verify_parameter_declarations (Ast0.undots d);
814 Ast0.wrap(Ast0.FunDecl((Ast0.default_info(),Ast0.context_befaft()),
34e49164
C
815 f, i,
816 P.clt2mcode "(" lp, d,
817 P.clt2mcode ")" rp,
818 P.clt2mcode "{" lb, b,
819 P.clt2mcode "}" rb)) }
820
821fninfo:
822 /* empty */ { [] }
823 | storage fninfo
824 { try
825 let _ =
826 List.find (function Ast0.FStorage(_) -> true | _ -> false) $2 in
827 raise (Semantic_cocci.Semantic "duplicate storage")
828 with Not_found -> (Ast0.FStorage($1))::$2 }
978fd7e5 829 | t=ctype r=fninfo_nt { (Ast0.FType(t))::r }
34e49164
C
830 | Tinline fninfo
831 { try
832 let _ = List.find (function Ast0.FInline(_) -> true | _ -> false) $2 in
833 raise (Semantic_cocci.Semantic "duplicate inline")
834 with Not_found -> (Ast0.FInline(P.clt2mcode "inline" $1))::$2 }
835 | Tattr fninfo
836 { try
837 let _ = List.find (function Ast0.FAttr(_) -> true | _ -> false) $2 in
838 raise (Semantic_cocci.Semantic "multiple attributes")
839 with Not_found -> (Ast0.FAttr(P.id2mcode $1))::$2 }
840
841fninfo_nt:
842 /* empty */ { [] }
843 | storage fninfo_nt
844 { try
845 let _ =
846 List.find (function Ast0.FStorage(_) -> true | _ -> false) $2 in
847 raise (Semantic_cocci.Semantic "duplicate storage")
848 with Not_found -> (Ast0.FStorage($1))::$2 }
849 | Tinline fninfo_nt
850 { try
851 let _ = List.find (function Ast0.FInline(_) -> true | _ -> false) $2 in
852 raise (Semantic_cocci.Semantic "duplicate inline")
853 with Not_found -> (Ast0.FInline(P.clt2mcode "inline" $1))::$2 }
854 | Tattr fninfo_nt
855 { try
856 let _ = List.find (function Ast0.FAttr(_) -> true | _ -> false) $2 in
857 raise (Semantic_cocci.Semantic "duplicate init")
858 with Not_found -> (Ast0.FAttr(P.id2mcode $1))::$2 }
859
860storage:
861 s=Tstatic { P.clt2mcode Ast.Static s }
862 | s=Tauto { P.clt2mcode Ast.Auto s }
863 | s=Tregister { P.clt2mcode Ast.Register s }
864 | s=Textern { P.clt2mcode Ast.Extern s }
865
866decl: t=ctype i=ident
867 { Ast0.wrap(Ast0.Param(t, Some i)) }
978fd7e5
C
868 | t=ctype { (*verify in FunDecl*) Ast0.wrap(Ast0.Param(t, None)) }
869 | t=ctype lp=TOPar s=TMul i=ident rp=TCPar
34e49164
C
870 lp1=TOPar d=decl_list(name_opt_decl) rp1=TCPar
871 { let fnptr =
872 Ast0.wrap
873 (Ast0.FunctionPointer
874 (t,P.clt2mcode "(" lp,P.clt2mcode "*" s,P.clt2mcode ")" rp,
875 P.clt2mcode "(" lp1,d,P.clt2mcode ")" rp1)) in
876 Ast0.wrap(Ast0.Param(fnptr, Some i)) }
34e49164
C
877 | TMetaParam
878 { let (nm,pure,clt) = $1 in
879 Ast0.wrap(Ast0.MetaParam(P.clt2mcode nm clt,pure)) }
880
881name_opt_decl:
882 decl { $1 }
978fd7e5 883 | t=ctype lp=TOPar s=TMul rp=TCPar
34e49164
C
884 lp1=TOPar d=decl_list(name_opt_decl) rp1=TCPar
885 { let fnptr =
886 Ast0.wrap
887 (Ast0.FunctionPointer
888 (t,P.clt2mcode "(" lp,P.clt2mcode "*" s,P.clt2mcode ")" rp,
889 P.clt2mcode "(" lp1,d,P.clt2mcode ")" rp1)) in
890 Ast0.wrap(Ast0.Param(fnptr, None)) }
891
892const_vol:
893 Tconst { P.clt2mcode Ast.Const $1 }
894 | Tvolatile { P.clt2mcode Ast.Volatile $1 }
895
896/*****************************************************************************/
897
898statement:
899 includes { $1 } /* shouldn't be allowed to be a single_statement... */
900| TMetaStm
901 { P.meta_stm $1 }
902| expr TPtVirg
903 { P.exp_stm $1 $2 }
904| TIf TOPar eexpr TCPar single_statement %prec TIf
905 { P.ifthen $1 $2 $3 $4 $5 }
906| TIf TOPar eexpr TCPar single_statement TElse single_statement
907 { P.ifthenelse $1 $2 $3 $4 $5 $6 $7 }
908| TFor TOPar option(eexpr) TPtVirg option(eexpr) TPtVirg
909 option(eexpr) TCPar single_statement
910 { P.forloop $1 $2 $3 $4 $5 $6 $7 $8 $9 }
911| TWhile TOPar eexpr TCPar single_statement
912 { P.whileloop $1 $2 $3 $4 $5 }
913| TDo single_statement TWhile TOPar eexpr TCPar TPtVirg
914 { P.doloop $1 $2 $3 $4 $5 $6 $7 }
915| iter_ident TOPar eexpr_list_option TCPar single_statement
916 { P.iterator $1 $2 $3 $4 $5 }
fc1ad971
C
917| TSwitch TOPar eexpr TCPar TOBrace list(decl_var) list(case_line) TCBrace
918 { P.switch $1 $2 $3 $4 $5 (List.concat $6) $7 $8 }
34e49164
C
919| TReturn eexpr TPtVirg { P.ret_exp $1 $2 $3 }
920| TReturn TPtVirg { P.ret $1 $2 }
921| TBreak TPtVirg { P.break $1 $2 }
922| TContinue TPtVirg { P.cont $1 $2 }
923| ident TDotDot { P.label $1 $2 }
924| TGoto ident TPtVirg { P.goto $1 $2 $3 }
925| TOBrace fun_start TCBrace
926 { P.seq $1 $2 $3 }
927
928stm_dots:
929 TEllipsis w=list(whenppdecs)
930 { Ast0.wrap(Ast0.Dots(P.clt2mcode "..." $1, List.concat w)) }
931| TOEllipsis w=list(whenppdecs) b=nest_start c=TCEllipsis
932 { Ast0.wrap(Ast0.Nest(P.clt2mcode "<..." $1, b,
933 P.clt2mcode "...>" c, List.concat w, false)) }
934| TPOEllipsis w=list(whenppdecs) b=nest_start c=TPCEllipsis
935 { Ast0.wrap(Ast0.Nest(P.clt2mcode "<+..." $1, b,
936 P.clt2mcode "...+>" c, List.concat w, true)) }
937
faf9a90c
C
938%inline stm_dots_ell:
939 a=TEllipsis w=list(whenppdecs)
940 { Ast0.wrap(Ast0.Dots(P.clt2mcode "..." a, List.concat w)) }
941
942%inline stm_dots_nest:
943 a=TOEllipsis w=list(whenppdecs) b=nest_start c=TCEllipsis
944 { Ast0.wrap(Ast0.Nest(P.clt2mcode "<..." a, b,
945 P.clt2mcode "...>" c, List.concat w, false)) }
946| a=TPOEllipsis w=list(whenppdecs) b=nest_start c=TPCEllipsis
947 { Ast0.wrap(Ast0.Nest(P.clt2mcode "<+..." a, b,
948 P.clt2mcode "...+>" c, List.concat w, true)) }
949
708f4980 950whenppdecs: w=whens(when_start,rule_elem_statement,any_strict)
34e49164
C
951 { w }
952
953/* a statement that fits into a single rule_elem. should nests be included?
954what about statement metavariables? */
955rule_elem_statement:
956 one_decl_var
957 { Ast0.wrap(Ast0.Decl((Ast0.default_info(),Ast0.context_befaft()),$1)) }
958| expr TPtVirg { P.exp_stm $1 $2 }
959| TReturn eexpr TPtVirg { P.ret_exp $1 $2 $3 }
960| TReturn TPtVirg { P.ret $1 $2 }
961| TBreak TPtVirg { P.break $1 $2 }
962| TContinue TPtVirg { P.cont $1 $2 }
963| TOPar0 midzero_list(rule_elem_statement,rule_elem_statement) TCPar0
964 { let (mids,code) = $2 in
965 Ast0.wrap
966 (Ast0.Disj(P.clt2mcode "(" $1,
967 List.map (function x -> Ast0.wrap(Ast0.DOTS([x]))) code,
968 mids, P.clt2mcode ")" $3)) }
969
970/* a statement on its own */
971single_statement:
972 statement { $1 }
973 | TOPar0 midzero_list(statement,statement) TCPar0
974 /* degenerate case, elements are single statements and thus don't
975 contain dots */
976 { let (mids,code) = $2 in
977 Ast0.wrap
978 (Ast0.Disj(P.clt2mcode "(" $1,
979 List.map (function x -> Ast0.wrap(Ast0.DOTS([x]))) code,
980 mids, P.clt2mcode ")" $3)) }
981
982case_line:
983 TDefault TDotDot fun_start
fc1ad971
C
984 { Ast0.wrap
985 (Ast0.Default(P.clt2mcode "default" $1,P.clt2mcode ":" $2,$3)) }
34e49164
C
986 | TCase eexpr TDotDot fun_start
987 { Ast0.wrap(Ast0.Case(P.clt2mcode "case" $1,$2,P.clt2mcode ":" $3,$4)) }
fc1ad971
C
988/* | lp=TOPar0 t=midzero_list(case_line,case_line) rp=TCPar0
989 { let (mids,code) = ([],[t]) in
990 Ast0.wrap
991 (Ast0.DisjCase(P.clt2mcode "(" lp,code,mids, P.clt2mcode ")" rp)) } */
34e49164
C
992
993/* In the following, an identifier as a type is not fully supported. Indeed,
994the language is ambiguous: what is foo * bar; */
995/* The AST DisjDecl cannot be generated because it would be ambiguous with
996a disjunction on a statement with a declaration in each branch */
997decl_var:
998 t=ctype pv=TPtVirg
999 { [Ast0.wrap(Ast0.TyDecl(t,P.clt2mcode ";" pv))] }
1000 | s=ioption(storage) t=ctype d=comma_list(d_ident) pv=TPtVirg
1001 { List.map
1002 (function (id,fn) ->
1003 Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)))
1004 d }
1005 | f=funproto { [f] }
1006 | s=ioption(storage) t=ctype d=d_ident q=TEq e=initialize pv=TPtVirg
1007 {let (id,fn) = d in
1008 [Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv))]}
1009 /* type is a typedef name */
1010 | s=ioption(storage) cv=ioption(const_vol) i=pure_ident
1011 d=comma_list(d_ident) pv=TPtVirg
1012 { List.map
1013 (function (id,fn) ->
1014 let idtype =
1015 P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
1016 Ast0.wrap(Ast0.UnInit(s,fn idtype,id,P.clt2mcode ";" pv)))
1017 d }
1018 | s=ioption(storage) cv=ioption(const_vol) i=pure_ident d=d_ident q=TEq
1019 e=initialize pv=TPtVirg
1020 { let (id,fn) = d in
1021 !Data.add_type_name (P.id2name i);
1022 let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
1023 [Ast0.wrap(Ast0.Init(s,fn idtype,id,P.clt2mcode "=" q,e,
1024 P.clt2mcode ";" pv))] }
1025 /* function pointer type */
1026 | s=ioption(storage)
978fd7e5 1027 t=ctype lp1=TOPar st=TMul d=d_ident rp1=TCPar
34e49164
C
1028 lp2=TOPar p=decl_list(name_opt_decl) rp2=TCPar
1029 pv=TPtVirg
1030 { let (id,fn) = d in
1031 let t =
1032 Ast0.wrap
1033 (Ast0.FunctionPointer
1034 (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
1035 P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
1036 [Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv))] }
1037 | decl_ident TOPar eexpr_list_option TCPar TPtVirg
1038 { [Ast0.wrap(Ast0.MacroDecl($1,P.clt2mcode "(" $2,$3,
faf9a90c 1039 P.clt2mcode ")" $4,P.clt2mcode ";" $5))] }
34e49164 1040 | s=ioption(storage)
978fd7e5 1041 t=ctype lp1=TOPar st=TMul d=d_ident rp1=TCPar
34e49164
C
1042 lp2=TOPar p=decl_list(name_opt_decl) rp2=TCPar
1043 q=TEq e=initialize pv=TPtVirg
1044 { let (id,fn) = d in
1045 let t =
1046 Ast0.wrap
1047 (Ast0.FunctionPointer
1048 (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
1049 P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
1050 [Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv))]}
002099fc 1051 | s=Ttypedef t=typedef_ctype id=comma_list(typedef_ident) pv=TPtVirg
34e49164 1052 { let s = P.clt2mcode "typedef" s in
002099fc
C
1053 List.map
1054 (function id ->
1055 Ast0.wrap(Ast0.Typedef(s,t,id,P.clt2mcode ";" pv)))
1056 id }
34e49164
C
1057
1058one_decl_var:
1059 t=ctype pv=TPtVirg
1060 { Ast0.wrap(Ast0.TyDecl(t,P.clt2mcode ";" pv)) }
1061 | s=ioption(storage) t=ctype d=d_ident pv=TPtVirg
1062 { let (id,fn) = d in
1063 Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)) }
1064 | f=funproto { f }
1065 | s=ioption(storage) t=ctype d=d_ident q=TEq e=initialize pv=TPtVirg
1066 { let (id,fn) = d in
1067 Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv)) }
1068 /* type is a typedef name */
1069 | s=ioption(storage) cv=ioption(const_vol) i=pure_ident
1070 d=d_ident pv=TPtVirg
1071 { let (id,fn) = d in
1072 let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
1073 Ast0.wrap(Ast0.UnInit(s,fn idtype,id,P.clt2mcode ";" pv)) }
1074 | s=ioption(storage) cv=ioption(const_vol) i=pure_ident d=d_ident q=TEq
1075 e=initialize pv=TPtVirg
1076 { let (id,fn) = d in
1077 !Data.add_type_name (P.id2name i);
1078 let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
1079 Ast0.wrap(Ast0.Init(s,fn idtype,id,P.clt2mcode "=" q,e,
1080 P.clt2mcode ";" pv)) }
1081 /* function pointer type */
1082 | s=ioption(storage)
978fd7e5 1083 t=ctype lp1=TOPar st=TMul d=d_ident rp1=TCPar
34e49164
C
1084 lp2=TOPar p=decl_list(name_opt_decl) rp2=TCPar
1085 pv=TPtVirg
1086 { let (id,fn) = d in
1087 let t =
1088 Ast0.wrap
1089 (Ast0.FunctionPointer
1090 (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
1091 P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
1092 Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)) }
1093 | decl_ident TOPar eexpr_list_option TCPar TPtVirg
1094 { Ast0.wrap(Ast0.MacroDecl($1,P.clt2mcode "(" $2,$3,
faf9a90c 1095 P.clt2mcode ")" $4,P.clt2mcode ";" $5)) }
34e49164 1096 | s=ioption(storage)
978fd7e5 1097 t=ctype lp1=TOPar st=TMul d=d_ident rp1=TCPar
34e49164
C
1098 lp2=TOPar p=decl_list(name_opt_decl) rp2=TCPar
1099 q=TEq e=initialize pv=TPtVirg
1100 { let (id,fn) = d in
1101 let t =
1102 Ast0.wrap
1103 (Ast0.FunctionPointer
1104 (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
1105 P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
1106 Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv))}
1107
1108
1109d_ident:
1110 ident list(array_dec)
1111 { ($1,
1112 function t ->
1113 List.fold_right
1114 (function (l,i,r) ->
1115 function rest ->
1116 Ast0.wrap
1117 (Ast0.Array(rest,P.clt2mcode "[" l,i,P.clt2mcode "]" r)))
1118 $2 t) }
1119
1120array_dec: l=TOCro i=option(eexpr) r=TCCro { (l,i,r) }
1121
1122initialize:
1123 eexpr
1124 { Ast0.wrap(Ast0.InitExpr($1)) }
1125 | TOBrace initialize_list TCBrace
1126 { Ast0.wrap(Ast0.InitList(P.clt2mcode "{" $1,$2,P.clt2mcode "}" $3)) }
1127 | TOBrace TCBrace
1128 { Ast0.wrap
1129 (Ast0.InitList(P.clt2mcode "{" $1,Ast0.wrap(Ast0.DOTS []),
1130 P.clt2mcode "}" $2)) }
113803cf
C
1131 | TMetaInit
1132 {let (nm,pure,clt) = $1 in
1133 Ast0.wrap(Ast0.MetaInit(P.clt2mcode nm clt,pure)) }
34e49164
C
1134
1135initialize2:
1136 /*arithexpr and not eexpr because can have ambiguity with comma*/
1137 /*dots and nests probably not allowed at top level, haven't looked into why*/
1138 arith_expr(eexpr,invalid) { Ast0.wrap(Ast0.InitExpr($1)) }
1139| TOBrace initialize_list TCBrace
1140 { Ast0.wrap(Ast0.InitList(P.clt2mcode "{" $1,$2,P.clt2mcode "}" $3)) }
1141| TOBrace TCBrace
1142 { Ast0.wrap
1143 (Ast0.InitList(P.clt2mcode "{" $1,Ast0.wrap(Ast0.DOTS []),
1144 P.clt2mcode "}" $2)) }
1145 /* gccext:, labeled elements */
113803cf
C
1146| list(designator) TEq initialize2
1147 { Ast0.wrap(Ast0.InitGccExt($1,P.clt2mcode "=" $2,$3)) }
34e49164
C
1148| ident TDotDot initialize2
1149 { Ast0.wrap(Ast0.InitGccName($1,P.clt2mcode ":" $2,$3)) } /* in old kernel */
113803cf 1150
951c7801
C
1151designator:
1152 | TDot ident
1153 { Ast0.DesignatorField (P.clt2mcode "." $1,$2) }
1154 | TOCro eexpr TCCro
113803cf 1155 { Ast0.DesignatorIndex (P.clt2mcode "[" $1,$2,P.clt2mcode "]" $3) }
951c7801 1156 | TOCro eexpr TEllipsis eexpr TCCro
113803cf
C
1157 { Ast0.DesignatorRange (P.clt2mcode "[" $1,$2,P.clt2mcode "..." $3,
1158 $4,P.clt2mcode "]" $5) }
34e49164
C
1159
1160initialize_list:
1161 initialize_list_start { Ast0.wrap(Ast0.DOTS($1)) }
1162
1163initialize_list_start:
1164 initialize2 TComma { [$1;Ast0.wrap(Ast0.IComma(P.clt2mcode "," $2))] }
1165| initialize2 TComma initialize_list_start
1166 { $1::Ast0.wrap(Ast0.IComma(P.clt2mcode "," $2))::$3 }
1167| d=edots_when(TEllipsis,initialize)
1168 r=comma_initializers(edots_when(TEllipsis,initialize))
1169 { (P.mkidots "..." d)::
1170 (List.concat(List.map (function x -> x (P.mkidots "...")) r)) }
1171
1172comma_initializers(dotter):
1173 /* empty */ { [] }
1174| d=dotter r=comma_initializers2(dotter)
1175 { (function dot_builder -> [dot_builder d])::r }
1176| i=initialize2 c=TComma r=comma_initializers(dotter)
1177 { (function dot_builder -> [i; Ast0.wrap(Ast0.IComma(P.clt2mcode "," c))])::
1178 r }
1179
1180comma_initializers2(dotter):
1181 /* empty */ { [] }
1182| i=initialize2 c=TComma r=comma_initializers(dotter)
1183 { (function dot_builder -> [i; Ast0.wrap(Ast0.IComma(P.clt2mcode "," c))])::
1184 r }
1185
1186/* a statement that is part of a list */
1187decl_statement:
1188 TMetaStmList
1189 { let (nm,pure,clt) = $1 in
1190 [Ast0.wrap(Ast0.MetaStmt(P.clt2mcode nm clt,pure))] }
1191 | decl_var
1192 { List.map
1193 (function x ->
1194 Ast0.wrap
1195 (Ast0.Decl((Ast0.default_info(),Ast0.context_befaft()),x)))
1196 $1 }
1197 | statement { [$1] }
1198 /* this doesn't allow expressions at top level, because the parser doesn't
1199 know whether there is one. If there is one, this is not sequencible.
1200 If there is not one, then it is. It seems complicated to get around
1201 this at the parser level. We would have to have a check afterwards to
1202 allow this. One case where this would be useful is for a when. Now
1203 we allow a sequence of whens, so one can be on only statements and
1204 one can be on only expressions. */
1205 | TOPar0 t=midzero_list(fun_start,fun_start) TCPar0
1206 { let (mids,code) = t in
1207 if List.for_all
1208 (function x ->
1209 match Ast0.unwrap x with Ast0.DOTS([]) -> true | _ -> false)
1210 code
1211 then []
1212 else
1213 [Ast0.wrap(Ast0.Disj(P.clt2mcode "(" $1, code, mids,
1214 P.clt2mcode ")" $3))] }
1215
1216/* a statement that is part of a list */
1217decl_statement_expr:
1218 TMetaStmList
1219 { let (nm,pure,clt) = $1 in
1220 [Ast0.wrap(Ast0.MetaStmt(P.clt2mcode nm clt,pure))] }
1221 | decl_var
1222 { List.map
1223 (function x ->
1224 Ast0.wrap
1225 (Ast0.Decl((Ast0.default_info(),Ast0.context_befaft()),x)))
1226 $1 }
1227 | statement { [$1] }
1228 /* this doesn't allow expressions at top level, because the parser doesn't
1229 know whether there is one. If there is one, this is not sequencible.
1230 If there is not one, then it is. It seems complicated to get around
1231 this at the parser level. We would have to have a check afterwards to
1232 allow this. One case where this would be useful is for a when. Now
1233 we allow a sequence of whens, so one can be on only statements and
1234 one can be on only expressions. */
1235 | TOPar0 t=midzero_list(fun_after_stm,fun_after_dots_or) TCPar0
1236 { let (mids,code) = t in
1237 if List.for_all (function [] -> true | _ -> false) code
1238 then []
1239 else
1240 let dot_code =
1241 List.map (function x -> Ast0.wrap(Ast0.DOTS x)) code in
1242 [Ast0.wrap(Ast0.Disj(P.clt2mcode "(" $1, dot_code, mids,
1243 P.clt2mcode ")" $3))] }
1244
1245/*****************************************************************************/
1246
1247/* The following cannot contain <... ...> at the top level. This can only
1248be allowed as an expression when the expression is delimited on both sides
1249by expression-specific markers. In that case, the rule eexpr is used, which
1250allows <... ...> anywhere. Hopefully, this will not be too much of a problem
1251in practice. */
1252expr: basic_expr(expr,invalid) { $1 }
1253/* allows ... and nests */
1254eexpr: basic_expr(eexpr,dot_expressions) { $1 }
1255/* allows nests but not .... */
1256dexpr: basic_expr(eexpr,nest_expressions) { $1 }
1257
1258top_eexpr:
1259 eexpr { Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp($1)))) }
1260
1261invalid:
1262 TInvalid { raise (Semantic_cocci.Semantic "not matchable") }
1263
1264dot_expressions:
1265 TEllipsis { Ast0.wrap(Ast0.Edots(P.clt2mcode "..." $1,None)) }
1266| nest_expressions { $1 }
1267
485bce71 1268/* not clear what whencode would mean, so just drop it */
34e49164 1269nest_expressions:
485bce71 1270 TOEllipsis e=expr_dots(TEllipsis) c=TCEllipsis
34e49164
C
1271 { Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<..." $1,
1272 Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
485bce71
C
1273 P.clt2mcode "...>" c, None, false)) }
1274| TPOEllipsis e=expr_dots(TEllipsis) c=TPCEllipsis
34e49164
C
1275 { Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<+..." $1,
1276 Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
485bce71 1277 P.clt2mcode "...+>" c, None, true)) }
34e49164 1278
485bce71 1279//whenexp: TWhen TNotEq w=eexpr TLineEnd { w }
34e49164
C
1280
1281basic_expr(recurser,primary_extra):
1282 assign_expr(recurser,primary_extra) { $1 }
1283
1284assign_expr(r,pe):
1285 cond_expr(r,pe) { $1 }
1286 | unary_expr(r,pe) TAssign assign_expr_bis
1287 { let (op,clt) = $2 in
1288 Ast0.wrap(Ast0.Assignment($1,P.clt2mcode op clt,
1289 Ast0.set_arg_exp $3,false)) }
1290 | unary_expr(r,pe) TEq assign_expr_bis
1291 { Ast0.wrap
1292 (Ast0.Assignment
1293 ($1,P.clt2mcode Ast.SimpleAssign $2,Ast0.set_arg_exp $3,false)) }
1294
1295assign_expr_bis:
1296 cond_expr(eexpr,dot_expressions) { $1 }
1297 | unary_expr(eexpr,dot_expressions) TAssign assign_expr_bis
1298 { let (op,clt) = $2 in
1299 Ast0.wrap(Ast0.Assignment($1,P.clt2mcode op clt,
1300 Ast0.set_arg_exp $3,false)) }
1301 | unary_expr(eexpr,dot_expressions) TEq assign_expr_bis
1302 { Ast0.wrap
1303 (Ast0.Assignment
1304 ($1,P.clt2mcode Ast.SimpleAssign $2,Ast0.set_arg_exp $3,false)) }
1305
1306cond_expr(r,pe):
1307 arith_expr(r,pe) { $1 }
1308 | l=arith_expr(r,pe) w=TWhy t=option(eexpr) dd=TDotDot r=cond_expr(r,pe)
1309 { Ast0.wrap(Ast0.CondExpr (l, P.clt2mcode "?" w, t,
1310 P.clt2mcode ":" dd, r)) }
1311
1312arith_expr(r,pe):
1313 cast_expr(r,pe) { $1 }
1314 | arith_expr(r,pe) TMul arith_expr(r,pe)
1315 { P.arith_op Ast.Mul $1 $2 $3 }
1316 | arith_expr(r,pe) TDmOp arith_expr(r,pe)
1317 { let (op,clt) = $2 in P.arith_op op $1 clt $3 }
1318 | arith_expr(r,pe) TPlus arith_expr(r,pe)
1319 { P.arith_op Ast.Plus $1 $2 $3 }
1320 | arith_expr(r,pe) TMinus arith_expr(r,pe)
1321 { P.arith_op Ast.Minus $1 $2 $3 }
1322 | arith_expr(r,pe) TShOp arith_expr(r,pe)
1323 { let (op,clt) = $2 in P.arith_op op $1 clt $3 }
1324 | arith_expr(r,pe) TLogOp arith_expr(r,pe)
1325 { let (op,clt) = $2 in P.logic_op op $1 clt $3 }
1326 | arith_expr(r,pe) TEqEq arith_expr(r,pe)
1327 { P.logic_op Ast.Eq $1 $2 $3 }
1328 | arith_expr(r,pe) TNotEq arith_expr(r,pe)
1329 { P.logic_op Ast.NotEq $1 $2 $3 }
1330 | arith_expr(r,pe) TAnd arith_expr(r,pe)
1331 { P.arith_op Ast.And $1 $2 $3 }
1332 | arith_expr(r,pe) TOr arith_expr(r,pe)
1333 { P.arith_op Ast.Or $1 $2 $3 }
1334 | arith_expr(r,pe) TXor arith_expr(r,pe)
1335 { P.arith_op Ast.Xor $1 $2 $3 }
1336 | arith_expr(r,pe) TAndLog arith_expr(r,pe)
1337 { P.logic_op Ast.AndLog $1 $2 $3 }
1338 | arith_expr(r,pe) TOrLog arith_expr(r,pe)
1339 { P.logic_op Ast.OrLog $1 $2 $3 }
1340
1341cast_expr(r,pe):
1342 unary_expr(r,pe) { $1 }
1343 | lp=TOPar t=ctype rp=TCPar e=cast_expr(r,pe)
1344 { Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t,
1345 P.clt2mcode ")" rp, e)) }
1346
1347unary_expr(r,pe):
1348 postfix_expr(r,pe) { $1 }
1349 | TInc unary_expr(r,pe)
1350 { Ast0.wrap(Ast0.Infix ($2, P.clt2mcode Ast.Inc $1)) }
1351 | TDec unary_expr(r,pe)
1352 { Ast0.wrap(Ast0.Infix ($2, P.clt2mcode Ast.Dec $1)) }
0708f913 1353 | unary_op cast_expr(r,pe)
34e49164
C
1354 { let mcode = $1 in Ast0.wrap(Ast0.Unary($2, mcode)) }
1355 | TBang unary_expr(r,pe)
1356 { let mcode = P.clt2mcode Ast.Not $1 in
1357 Ast0.wrap(Ast0.Unary($2, mcode)) }
1358 | TSizeof unary_expr(r,pe)
1359 { Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" $1, $2)) }
1360 | s=TSizeof lp=TOPar t=ctype rp=TCPar
1361 { Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s,
1362 P.clt2mcode "(" lp,t,
1363 P.clt2mcode ")" rp)) }
1364
1365unary_op: TAnd { P.clt2mcode Ast.GetRef $1 }
1366 | TMul { P.clt2mcode Ast.DeRef $1 }
1367 | TPlus { P.clt2mcode Ast.UnPlus $1 }
1368 | TMinus { P.clt2mcode Ast.UnMinus $1 }
1369 | TTilde { P.clt2mcode Ast.Tilde $1 }
1370
1371postfix_expr(r,pe):
1372 primary_expr(r,pe) { $1 }
1373 | postfix_expr(r,pe) TOCro eexpr TCCro
1374 { Ast0.wrap(Ast0.ArrayAccess ($1,P.clt2mcode "[" $2,$3,
1375 P.clt2mcode "]" $4)) }
1376 | postfix_expr(r,pe) TDot ident
1377 { Ast0.wrap(Ast0.RecordAccess($1, P.clt2mcode "." $2, $3)) }
1378 | postfix_expr(r,pe) TPtrOp ident
1379 { Ast0.wrap(Ast0.RecordPtAccess($1, P.clt2mcode "->" $2,
1380 $3)) }
1381 | postfix_expr(r,pe) TInc
1382 { Ast0.wrap(Ast0.Postfix ($1, P.clt2mcode Ast.Inc $2)) }
1383 | postfix_expr(r,pe) TDec
1384 { Ast0.wrap(Ast0.Postfix ($1, P.clt2mcode Ast.Dec $2)) }
1385 | postfix_expr(r,pe) TOPar eexpr_list_option TCPar
1386 { Ast0.wrap(Ast0.FunCall($1,P.clt2mcode "(" $2,
1387 $3,
1388 P.clt2mcode ")" $4)) }
1389
1390primary_expr(recurser,primary_extra):
1391 func_ident { Ast0.wrap(Ast0.Ident($1)) }
1392 | TInt
1393 { let (x,clt) = $1 in
1394 Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) }
1395 | TFloat
1396 { let (x,clt) = $1 in
1397 Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) }
1398 | TString
1399 { let (x,clt) = $1 in
1400 Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) }
1401 | TChar
1402 { let (x,clt) = $1 in
1403 Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) }
1404 | TMetaConst
1405 { let (nm,constraints,pure,ty,clt) = $1 in
1406 Ast0.wrap
1407 (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.CONST,pure)) }
1408 | TMetaErr
1409 { let (nm,constraints,pure,clt) = $1 in
1410 Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) }
1411 | TMetaExp
1412 { let (nm,constraints,pure,ty,clt) = $1 in
1413 Ast0.wrap
1414 (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ANY,pure)) }
1415 | TMetaIdExp
1416 { let (nm,constraints,pure,ty,clt) = $1 in
1417 Ast0.wrap
1418 (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ID,pure)) }
1419 | TMetaLocalIdExp
1420 { let (nm,constraints,pure,ty,clt) = $1 in
1421 Ast0.wrap
1422 (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.LocalID,pure)) }
1423 | TOPar eexpr TCPar
1424 { Ast0.wrap(Ast0.Paren(P.clt2mcode "(" $1,$2,
1425 P.clt2mcode ")" $3)) }
1426 | TOPar0 midzero_list(recurser,eexpr) TCPar0
1427 { let (mids,code) = $2 in
1428 Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" $1,
1429 code, mids,
1430 P.clt2mcode ")" $3)) }
1431 | primary_extra { $1 }
1432
1433expr_dots(dotter):
1434 r=no_dot_start_end(dexpr,edots_when(dotter,eexpr)) { r }
1435
1436// used in NEST
1437no_dot_start_end(grammar,dotter):
1438 g=grammar dg=list(pair(dotter,grammar))
1439 { function dot_builder ->
1440 g :: (List.concat(List.map (function (d,g) -> [dot_builder d;g]) dg)) }
1441
1442/*****************************************************************************/
1443
1444pure_ident:
1445 TIdent { $1 }
1446
ae4735db
C
1447pure_ident_kwd:
1448 | TIdentifier { "identifier" }
1449 | TExpression { "expression" }
1450 | TStatement { "statement" }
1451 | TFunction { "function" }
1452 | TLocal { "local" }
1453 | TType { "type" }
1454 | TParameter { "parameter" }
1455 | TIdExpression { "idexpression" }
1456 | TInitialiser { "initialiser" }
1457 | Tlist { "list" }
1458 | TFresh { "fresh" }
1459 | TConstant { "constant" }
1460 | TError { "error" }
1461 | TWords { "words" }
1462 | TPure { "pure" }
1463 | TContext { "context" }
1464 | TGenerated { "generated" }
1465 | TTypedef { "typedef" }
1466 | TDeclarer { "declarer" }
1467 | TIterator { "iterator" }
1468 | TName { "name" }
1469 | TPosition { "position" }
1470
34e49164 1471meta_ident:
ae4735db
C
1472 TRuleName TDot pure_ident { (Some $1,P.id2name $3) }
1473 | TRuleName TDot pure_ident_kwd { (Some $1,$3) }
34e49164
C
1474
1475pure_ident_or_meta_ident:
1476 pure_ident { (None,P.id2name $1) }
ae4735db 1477 | pure_ident_kwd { (None,$1) }
34e49164 1478 | meta_ident { $1 }
34e49164 1479
b1b2de81 1480pure_ident_or_meta_ident_with_seed:
978fd7e5
C
1481 pure_ident_or_meta_ident { ($1,Ast.NoVal) }
1482 | pure_ident_or_meta_ident TEq
1483 separated_nonempty_list(TCppConcatOp,seed_elem)
1484 { match $3 with
1485 [Ast.SeedString s] -> ($1,Ast.StringSeed s)
1486 | _ -> ($1,Ast.ListSeed $3) }
1487
1488seed_elem:
1489 TString { let (x,_) = $1 in Ast.SeedString x }
1490| TMetaId { let (x,_,_,_) = $1 in Ast.SeedId x }
1491| TRuleName TDot pure_ident
1492 { let nm = ($1,P.id2name $3) in
1493 P.check_meta(Ast.MetaIdDecl(Ast.NONE,nm));
1494 Ast.SeedId nm }
b1b2de81 1495
951c7801
C
1496pure_ident_or_meta_ident_with_x_eq(x_eq):
1497 i=pure_ident_or_meta_ident l=loption(x_eq)
1498 {
1499 (i, l)
1500 }
1501
1502pure_ident_or_meta_ident_with_econstraint(x_eq):
1503 i=pure_ident_or_meta_ident optc=option(x_eq)
1504 {
1505 match optc with
1506 None -> (i, Ast0.NoConstraint)
1507 | Some c -> (i, c)
1508 }
1509
ae4735db
C
1510pure_ident_or_meta_ident_with_idconstraint_virt(constraint_type):
1511 i=pure_ident_or_meta_ident c=option(constraint_type)
1512 {
1513 Common.Left
1514 (match c with
1515 None -> (i, Ast.IdNoConstraint)
1516 | Some constraint_ -> (i,constraint_))
1517 }
1518| TVirtual TDot pure_ident { Common.Right (P.id2name $3) }
1519
951c7801
C
1520pure_ident_or_meta_ident_with_idconstraint(constraint_type):
1521 i=pure_ident_or_meta_ident c=option(constraint_type)
1522 {
1523 match c with
1524 None -> (i, Ast.IdNoConstraint)
1525 | Some constraint_ -> (i,constraint_)
1526 }
1527
1528re_or_not_eqid:
5636bb2c 1529 re=regexp_eqid {Ast.IdRegExpConstraint re}
951c7801
C
1530 | ne=not_eqid {ne}
1531
1532regexp_eqid:
5636bb2c 1533 TTildeEq re=TString
951c7801
C
1534 { (if !Data.in_iso
1535 then failwith "constraints not allowed in iso file");
1536 (if !Data.in_generating
1537 then failwith "constraints not allowed in a generated rule file");
1538 let (s,_) = re in Ast.IdRegExp (s,Str.regexp s)
1539 }
1540 | TTildeExclEq re=TString
1541 { (if !Data.in_iso
1542 then failwith "constraints not allowed in iso file");
1543 (if !Data.in_generating
1544 then failwith "constraints not allowed in a generated rule file");
1545 let (s,_) = re in Ast.IdNotRegExp (s,Str.regexp s)
1546 }
34e49164 1547
951c7801 1548not_eqid:
c3e37e97 1549 TNotEq i=pure_ident_or_meta_ident
34e49164
C
1550 { (if !Data.in_iso
1551 then failwith "constraints not allowed in iso file");
faf9a90c
C
1552 (if !Data.in_generating
1553 (* pb: constraints not stored with metavars; too lazy to search for
1554 them in the pattern *)
1555 then failwith "constraints not allowed in a generated rule file");
5636bb2c
C
1556 (match i with
1557 (Some rn,id) ->
1558 let i =
1559 P.check_inherited_constraint i
1560 (function mv -> Ast.MetaIdDecl(Ast.NONE,mv)) in
1561 Ast.IdNegIdSet([],[i])
1562 | (None,i) -> Ast.IdNegIdSet([i],[])) }
c3e37e97 1563 | TNotEq TOBrace l=comma_list(pure_ident_or_meta_ident) TCBrace
34e49164
C
1564 { (if !Data.in_iso
1565 then failwith "constraints not allowed in iso file");
faf9a90c
C
1566 (if !Data.in_generating
1567 then failwith "constraints not allowed in a generated rule file");
5636bb2c
C
1568 let (str,meta) =
1569 List.fold_left
1570 (function (str,meta) ->
1571 function
1572 (Some rn,id) as i ->
1573 let i =
1574 P.check_inherited_constraint i
1575 (function mv -> Ast.MetaIdDecl(Ast.NONE,mv)) in
1576 (str,i::meta)
1577 | (None,i) -> (i::str,meta))
1578 ([],[]) l in
1579 Ast.IdNegIdSet(str,meta)
951c7801
C
1580 }
1581
5636bb2c
C
1582re_or_not_eqe_or_sub:
1583 re=regexp_eqid {Ast0.NotIdCstrt re}
1584 | ne=not_eqe {Ast0.NotExpCstrt ne}
1585 | s=sub {Ast0.SubExpCstrt s}
1586
1587not_ceq_or_sub:
1588 ceq=not_ceq {Ast0.NotExpCstrt ceq}
1589 | s=sub {Ast0.SubExpCstrt s}
34e49164
C
1590
1591not_eqe:
1592 TNotEq i=pure_ident
1593 { (if !Data.in_iso
1594 then failwith "constraints not allowed in iso file");
faf9a90c
C
1595 (if !Data.in_generating
1596 then failwith "constraints not allowed in a generated rule file");
951c7801
C
1597 [Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i))))]
1598 }
34e49164
C
1599 | TNotEq TOBrace l=comma_list(pure_ident) TCBrace
1600 { (if !Data.in_iso
1601 then failwith "constraints not allowed in iso file");
faf9a90c
C
1602 (if !Data.in_generating
1603 then failwith "constraints not allowed in a generated rule file");
34e49164
C
1604 List.map
1605 (function i ->
951c7801
C
1606 Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i)))))
1607 l
1608 }
34e49164
C
1609
1610not_ceq:
1611 TNotEq i=ident_or_const
1612 { (if !Data.in_iso
1613 then failwith "constraints not allowed in iso file");
faf9a90c
C
1614 (if !Data.in_generating
1615 then failwith "constraints not allowed in a generated rule file");
34e49164
C
1616 [i] }
1617 | TNotEq TOBrace l=comma_list(ident_or_const) TCBrace
1618 { (if !Data.in_iso
1619 then failwith "constraints not allowed in iso file");
faf9a90c
C
1620 (if !Data.in_generating
1621 then failwith "constraints not allowed in a generated rule file");
34e49164
C
1622 l }
1623
5636bb2c
C
1624sub:
1625 (* has to be inherited because not clear how to check subterm constraints
1626 in the functorized CTL engine, so need the variable to be bound
1627 already when bind the subterm constrained metavariable *)
1628 TSub i=meta_ident
1629 { (if !Data.in_iso
1630 then failwith "constraints not allowed in iso file");
1631 (if !Data.in_generating
1632 then failwith "constraints not allowed in a generated rule file");
1633 let i =
1634 P.check_inherited_constraint i
1635 (function mv -> Ast.MetaExpDecl(Ast.NONE,mv,None)) in
1636 [i] }
1637 | TSub TOBrace l=comma_list(meta_ident) TCBrace
1638 { (if !Data.in_iso
1639 then failwith "constraints not allowed in iso file");
1640 (if !Data.in_generating
1641 then failwith "constraints not allowed in a generated rule file");
1642 List.map
1643 (function i ->
1644 P.check_inherited_constraint i
1645 (function mv -> Ast.MetaExpDecl(Ast.NONE,mv,None)))
1646 l}
1647
34e49164
C
1648ident_or_const:
1649 i=pure_ident { Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i)))) }
1650 | TInt
1651 { let (x,clt) = $1 in
1652 Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) }
1653
1654not_pos:
1655 TNotEq i=meta_ident
1656 { (if !Data.in_iso
1657 then failwith "constraints not allowed in iso file");
faf9a90c
C
1658 (if !Data.in_generating
1659 then failwith "constraints not allowed in a generated rule file");
5636bb2c
C
1660 let i =
1661 P.check_inherited_constraint i
1662 (function mv -> Ast.MetaPosDecl(Ast.NONE,mv)) in
1663 [i] }
34e49164
C
1664 | TNotEq TOBrace l=comma_list(meta_ident) TCBrace
1665 { (if !Data.in_iso
1666 then failwith "constraints not allowed in iso file");
faf9a90c
C
1667 (if !Data.in_generating
1668 then failwith "constraints not allowed in a generated rule file");
34e49164 1669 List.map
5636bb2c
C
1670 (function i ->
1671 P.check_inherited_constraint i
1672 (function mv -> Ast.MetaPosDecl(Ast.NONE,mv)))
34e49164
C
1673 l }
1674
1675func_ident: pure_ident
1676 { Ast0.wrap(Ast0.Id(P.id2mcode $1)) }
1677 | TMetaId
1678 { let (nm,constraints,pure,clt) = $1 in
1679 Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) }
1680 | TMetaFunc
1681 { let (nm,constraints,pure,clt) = $1 in
1682 Ast0.wrap(Ast0.MetaFunc(P.clt2mcode nm clt,constraints,pure)) }
1683 | TMetaLocalFunc
1684 { let (nm,constraints,pure,clt) = $1 in
1685 Ast0.wrap
1686 (Ast0.MetaLocalFunc(P.clt2mcode nm clt,constraints,pure)) }
1687
1688ident: pure_ident
1689 { Ast0.wrap(Ast0.Id(P.id2mcode $1)) }
1690 | TMetaId
1691 { let (nm,constraints,pure,clt) = $1 in
1692 Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) }
1693
1694decl_ident:
1695 TDeclarerId
1696 { Ast0.wrap(Ast0.Id(P.id2mcode $1)) }
1697 | TMetaDeclarer
1698 { let (nm,constraints,pure,clt) = $1 in
1699 Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) }
1700
1701iter_ident:
1702 TIteratorId
1703 { Ast0.wrap(Ast0.Id(P.id2mcode $1)) }
1704 | TMetaIterator
1705 { let (nm,constraints,pure,clt) = $1 in
1706 Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) }
1707
1708typedef_ident:
1709 pure_ident
1710 { Ast0.wrap(Ast0.TypeName(P.id2mcode $1)) }
1711 | TMetaType
1712 { let (nm,pure,clt) = $1 in
1713 Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure)) }
1714
1715/*****************************************************************************/
1716
1717decl_list(decl):
113803cf
C
1718 /* empty */ { Ast0.wrap(Ast0.DOTS([])) }
1719| decl_list_start(decl)
34e49164
C
1720 {let circle x =
1721 match Ast0.unwrap x with Ast0.Pcircles(_) -> true | _ -> false in
1722 if List.exists circle $1
1723 then Ast0.wrap(Ast0.CIRCLES($1))
1724 else Ast0.wrap(Ast0.DOTS($1)) }
1725
1726decl_list_start(decl):
1727 one_dec(decl) { [$1] }
1728| one_dec(decl) TComma decl_list_start(decl)
1729 { $1::Ast0.wrap(Ast0.PComma(P.clt2mcode "," $2))::$3 }
1730| TEllipsis list(comma_decls(TEllipsis,decl))
1731 { Ast0.wrap(Ast0.Pdots(P.clt2mcode "..." $1))::
1732 (List.concat(List.map (function x -> x (P.mkpdots "...")) $2)) }
1733
1734one_dec(decl):
1735 decl { $1 }
1736| TMetaParamList
1737 { let (nm,lenname,pure,clt) = $1 in
1738 let nm = P.clt2mcode nm clt in
1739 let lenname =
1740 match lenname with
1741 Some nm -> Some(P.clt2mcode nm clt)
1742 | None -> None in
1743 Ast0.wrap(Ast0.MetaParamList(nm,lenname,pure)) }
faf9a90c 1744
34e49164
C
1745comma_decls(dotter,decl):
1746 TComma dotter
1747 { function dot_builder ->
1748 [Ast0.wrap(Ast0.PComma(P.clt2mcode "," $1));
1749 dot_builder $2] }
1750| TComma one_dec(decl)
1751 { function dot_builder ->
1752 [Ast0.wrap(Ast0.PComma(P.clt2mcode "," $1)); $2] }
1753
1754/* ---------------------------------------------------------------------- */
1755
978fd7e5
C
1756/* error words make it complicated to be able to use error as a metavariable
1757name or a type in a metavariable list; for that we would like to allow TError
1758as an ident, but that makes conflicts with this rule. To add back error words,
1759need to find some appropriate delimiter for it, but it has not been used much
1760so just drop it */
1761/*error_words:
34e49164
C
1762 TError TWords TEq TOCro cl=comma_list(dexpr) TCCro
1763 { [Ast0.wrap(Ast0.ERRORWORDS(cl))] }
978fd7e5 1764*/
34e49164
C
1765
1766/* ---------------------------------------------------------------------- */
1767/* sequences of statements and expressions */
1768
1769/* There are number of cases that must be considered:
1770
17711. Top level:
1772 Dots and nests allowed at the beginning or end
1773 Expressions allowed at the beginning or end
1774 One function allowed, by itself
17752. A function body:
1776 Dots and nests allowed at the beginning or end
1777 Expressions not allowed at the beginning or end
1778 Functions not allowed
17793. The body of a nest:
1780 Dots and nests not allowed at the beginning or end
1781 Expressions allowed at the beginning or end
1782 Functions not allowed
17834. Whencode:
1784 Dots and nests not allowed at the beginning but allowed at the end
1785 Expressions allowed at the beginning or end
1786 Functions not allowed
1787
1788These are implemented by the rules minus_toplevel_sequence,
1789plus_toplevel_sequence, function_body_sequence, nest_body_sequence, and
1790when_body_sequence.
1791*/
1792/* ------------------------------------------------------------------------ */
1793/* Minus top level */
1794
1795/* doesn't allow only ... */
1796minus_start:
1797 fundecl { [Ast0.wrap(Ast0.DECL($1))] }
1798| ctype { [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Ty($1))))] }
1be43e12 1799| top_init { [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.TopInit($1))))] }
faf9a90c 1800| toplevel_seq_startne(toplevel_after_dots_init)
34e49164
C
1801 { List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1 }
1802
faf9a90c
C
1803toplevel_seq_startne(after_dots_init):
1804 a=stm_dots_ell b=after_dots_init { a::b }
1805| a=stm_dots_nest b=after_dots_init { a::b }
1806| a=stm_dots_nest { [a] }
1807| expr toplevel_after_exp { (Ast0.wrap(Ast0.Exp($1)))::$2 }
1808| decl_statement_expr toplevel_after_stm { $1@$2 }
1809
34e49164
C
1810toplevel_seq_start(after_dots_init):
1811 stm_dots after_dots_init { $1::$2 }
1812| expr toplevel_after_exp { (Ast0.wrap(Ast0.Exp($1)))::$2 }
1813| decl_statement_expr toplevel_after_stm { $1@$2 }
1814
1815toplevel_after_dots_init:
1816 TNothing toplevel_after_exp {$2}
1817| expr toplevel_after_exp {(Ast0.wrap(Ast0.Exp($1)))::$2}
1818| decl_statement_expr toplevel_after_stm {$1@$2}
1819
1820toplevel_after_exp:
1821 /* empty */ {[]}
1822| stm_dots toplevel_after_dots {$1::$2}
1823
1824toplevel_after_dots:
1825 /* empty */ {[]}
1826| TNothing toplevel_after_exp {$2}
1827| expr toplevel_after_exp {(Ast0.wrap(Ast0.Exp($1)))::$2}
1828| decl_statement_expr toplevel_after_stm {$1@$2}
1829
1830toplevel_after_stm:
1831 /* empty */ {[]}
1832| stm_dots toplevel_after_dots {$1::$2}
1833| decl_statement toplevel_after_stm {$1@$2}
1834
1be43e12
C
1835top_init:
1836 TOInit initialize_list TCBrace
1837 { Ast0.wrap(Ast0.InitList(P.clt2mcode "{" $1,$2,P.clt2mcode "}" $3)) }
1838
34e49164
C
1839/* ------------------------------------------------------------------------ */
1840/* Plus top level */
1841
1842/* does allow only ... also allows multiple top-level functions */
1843plus_start:
1844 ctype { [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Ty($1))))] }
1be43e12 1845| top_init { [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.TopInit($1))))] }
34e49164
C
1846| stm_dots plus_after_dots
1847 { (Ast0.wrap(Ast0.OTHER($1)))::$2 }
1848| expr plus_after_exp
1849 { (Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp($1)))))::$2 }
1850| fundecl plus_after_stm { Ast0.wrap(Ast0.DECL($1))::$2 }
1851| decl_statement_expr plus_after_stm
1852 { (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1)@$2 }
1853
1854plus_after_exp:
1855 /* empty */ {[]}
1856| stm_dots plus_after_dots { (Ast0.wrap(Ast0.OTHER($1)))::$2 }
1857
1858plus_after_dots:
1859 /* empty */ {[]}
1860| TNothing plus_after_exp {$2}
1861| expr plus_after_exp
1862 { (Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp($1)))))::$2 }
1863| fundecl plus_after_stm { Ast0.wrap(Ast0.DECL($1))::$2 }
1864| decl_statement_expr plus_after_stm
1865 { (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1)@$2 }
1866
1867plus_after_stm:
1868 /* empty */ {[]}
1869| stm_dots plus_after_dots { (Ast0.wrap(Ast0.OTHER($1)))::$2 }
1870| fundecl plus_after_stm { Ast0.wrap(Ast0.DECL($1))::$2 }
1871| decl_statement plus_after_stm
1872 { (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1)@$2 }
1873
1874/* ------------------------------------------------------------------------ */
1875/* Function body */
1876
1877fun_start:
1878 fun_after_stm { Ast0.wrap(Ast0.DOTS($1)) }
1879
1880fun_after_stm:
1881 /* empty */ {[]}
1882| stm_dots fun_after_dots {$1::$2}
1883| decl_statement fun_after_stm {$1@$2}
1884
1885fun_after_dots:
1886 /* empty */ {[]}
1887| TNothing fun_after_exp {$2}
1888| expr fun_after_exp {Ast0.wrap(Ast0.Exp($1))::$2}
1889| decl_statement_expr fun_after_stm {$1@$2}
1890
1891fun_after_exp:
1892 stm_dots fun_after_dots {$1::$2}
1893
1894/* hack to allow mixing statements and expressions in an or */
1895fun_after_dots_or:
1896 /* empty */ {[]}
1897| TNothing fun_after_exp_or {$2}
1898| expr fun_after_exp_or {Ast0.wrap(Ast0.Exp($1))::$2}
1899| decl_statement_expr fun_after_stm {$1@$2}
1900
1901fun_after_exp_or:
1902 /* empty */ {[]}
1903| stm_dots fun_after_dots {$1::$2}
1904
1905/* ------------------------------------------------------------------------ */
1906/* Nest body */
1907
1908nest_start:
1909 nest_after_dots { Ast0.wrap(Ast0.DOTS($1)) }
1910
1911nest_after_dots:
1912 decl_statement_expr nest_after_stm {$1@$2}
1913| TNothing nest_after_exp {$2}
1914| expr nest_after_exp {(Ast0.wrap(Ast0.Exp($1)))::$2}
1915
1916nest_after_stm:
1917 /* empty */ {[]}
1918| stm_dots nest_after_dots {$1::$2}
1919| decl_statement nest_after_stm {$1@$2}
1920
1921nest_after_exp:
1922 /* empty */ {[]}
1923| stm_dots nest_after_dots {$1::$2}
1924
1925/* ------------------------------------------------------------------------ */
1926/*Whencode*/
1927
1928when_start:
1929 expr toplevel_after_exp
1930 { Ast0.wrap(Ast0.DOTS((Ast0.wrap(Ast0.Exp($1)))::$2)) }
1931| decl_statement toplevel_after_stm
1932 { Ast0.wrap(Ast0.DOTS($1@$2)) }
1933
1934/* ---------------------------------------------------------------------- */
1935
1936eexpr_list:
1937 eexpr_list_start
1938 {let circle x =
1939 match Ast0.unwrap x with Ast0.Ecircles(_) -> true | _ -> false in
1940 let star x =
1941 match Ast0.unwrap x with Ast0.Estars(_) -> true | _ -> false in
1942 if List.exists circle $1
1943 then Ast0.wrap(Ast0.CIRCLES($1))
1944 else
1945 if List.exists star $1
1946 then Ast0.wrap(Ast0.STARS($1))
1947 else Ast0.wrap(Ast0.DOTS($1)) }
1948
1949/* arg expr. may contain a type or a explist metavariable */
1950aexpr:
1951 eexpr
1952 { Ast0.set_arg_exp $1 }
1953 | TMetaExpList
1954 { let (nm,lenname,pure,clt) = $1 in
1955 let nm = P.clt2mcode nm clt in
1956 let lenname =
1957 match lenname with
1958 Some nm -> Some(P.clt2mcode nm clt)
1959 | None -> None in
1960 Ast0.wrap(Ast0.MetaExprList(nm,lenname,pure)) }
1961 | ctype
1962 { Ast0.set_arg_exp(Ast0.wrap(Ast0.TypeExp($1))) }
1963
1964eexpr_list_start:
1965 aexpr { [$1] }
1966 | aexpr TComma eexpr_list_start
1967 { $1::Ast0.wrap(Ast0.EComma(P.clt2mcode "," $2))::$3 }
1968
1969comma_args(dotter):
1970 c=TComma d=dotter
1971 { function dot_builder ->
1972 [Ast0.wrap(Ast0.EComma(P.clt2mcode "," c)); dot_builder d] }
1973| TComma aexpr
1974 { function dot_builder ->
1975 [Ast0.wrap(Ast0.EComma(P.clt2mcode "," $1)); $2] }
1976
1977eexpr_list_option: eexpr_list { $1 }
1978 | /* empty */ { Ast0.wrap(Ast0.DOTS([])) }
1979
1980/****************************************************************************/
1981
1982// non-empty lists - drop separator
1983comma_list(elem):
1984 separated_nonempty_list(TComma,elem) { $1 }
1985
1986midzero_list(elem,aft):
1987 a=elem b=list(mzl(aft))
1988 { let (mids,code) = List.split b in (mids,(a::code)) }
1989
1990mzl(elem):
1991 a=TMid0 b=elem { (P.clt2mcode "|" a, b) }
1992
1993edots_when(dotter,when_grammar):
1994 d=dotter { (d,None) }
1995 | d=dotter TWhen TNotEq w=when_grammar TLineEnd { (d,Some w) }
1996
708f4980 1997whens(when_grammar,simple_when_grammar,any_strict):
34e49164
C
1998 TWhen TNotEq w=when_grammar TLineEnd { [Ast0.WhenNot w] }
1999 | TWhen TEq w=simple_when_grammar TLineEnd { [Ast0.WhenAlways w] }
2000 | TWhen comma_list(any_strict) TLineEnd
2001 { List.map (function x -> Ast0.WhenModifier(x)) $2 }
1be43e12
C
2002 | TWhenTrue TNotEq e = eexpr TLineEnd { [Ast0.WhenNotTrue e] }
2003 | TWhenFalse TNotEq e = eexpr TLineEnd { [Ast0.WhenNotFalse e] }
34e49164
C
2004
2005any_strict:
2006 TAny { Ast.WhenAny }
2007 | TStrict { Ast.WhenStrict }
2008 | TForall { Ast.WhenForall }
2009 | TExists { Ast.WhenExists }
2010
2011/*****************************************************************************
2012*
2013*
2014*****************************************************************************/
2015
2016iso_main:
c3e37e97
C
2017 TIsoExpression e1=eexpr el=list(iso(eexpr)) EOF
2018 { let fn x = Ast0.ExprTag x in P.iso_adjust fn fn e1 el }
2019| TIsoArgExpression e1=eexpr el=list(iso(eexpr)) EOF
2020 { let fn x = Ast0.ArgExprTag x in P.iso_adjust fn fn e1 el }
2021| TIsoTestExpression e1=eexpr el=list(iso(eexpr)) EOF
2022 { let fn x = Ast0.TestExprTag x in P.iso_adjust fn fn e1 el }
2023| TIsoToTestExpression e1=eexpr el=list(iso(eexpr)) EOF
2024 { let ffn x = Ast0.ExprTag x in
2025 let fn x = Ast0.TestExprTag x in
2026 P.iso_adjust ffn fn e1 el }
34e49164 2027| TIsoStatement s1=single_statement sl=list(iso(single_statement)) EOF
c3e37e97 2028 { let fn x = Ast0.StmtTag x in P.iso_adjust fn fn s1 sl }
34e49164 2029| TIsoType t1=ctype tl=list(iso(ctype)) EOF
c3e37e97 2030 { let fn x = Ast0.TypeCTag x in P.iso_adjust fn fn t1 tl }
34e49164 2031| TIsoTopLevel e1=nest_start el=list(iso(nest_start)) EOF
c3e37e97 2032 { let fn x = Ast0.DotsStmtTag x in P.iso_adjust fn fn e1 el }
34e49164
C
2033| TIsoDeclaration d1=decl_var dl=list(iso(decl_var)) EOF
2034 { let check_one = function
2035 [x] -> x
2036 | _ ->
2037 raise
2038 (Semantic_cocci.Semantic
2039 "only one variable per declaration in an isomorphism rule") in
2040 let d1 = check_one d1 in
2041 let dl =
2042 List.map
2043 (function
2044 Common.Left x -> Common.Left(check_one x)
2045 | Common.Right x -> Common.Right(check_one x))
2046 dl in
c3e37e97 2047 let fn x = Ast0.DeclTag x in P.iso_adjust fn fn d1 dl }
34e49164
C
2048
2049iso(term):
2050 TIso t=term { Common.Left t }
2051 | TRightIso t=term { Common.Right t }
2052
2053/*****************************************************************************
2054*
2055*
2056*****************************************************************************/
2057
2058never_used: TPragma { () }
2059 | TPArob TMetaPos { () }
2060 | TScriptData { () }
2061
ae4735db
C
2062script_meta_main:
2063 py=pure_ident TShOp TRuleName TDot cocci=pure_ident TMPtVirg
34e49164 2064 { (P.id2name py, ($3, P.id2name cocci)) }
ae4735db
C
2065 | py=pure_ident TShOp TVirtual TDot cocci=pure_ident TMPtVirg
2066 { (P.id2name py, ("virtual", P.id2name cocci)) }