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