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