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