*/
+/*
+ * Copyright 2010, INRIA, University of Copenhagen
+ * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
+ * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
+ * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
+ * This file is part of Coccinelle.
+ *
+ * Coccinelle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, according to version 2 of the License.
+ *
+ * Coccinelle is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The authors reserve the right to distribute this or future versions of
+ * Coccinelle under other licenses.
+ */
+
+
%{
(* Not clear how to allow function declarations to specify a return type
%token EOF
%token TIdentifier TExpression TStatement TFunction TLocal TType TParameter
-%token TIdExpression TInitialiser
+%token TIdExpression TInitialiser TDeclaration TField
%token Tlist TFresh TConstant TError TWords TWhy0 TPlus0 TBang0
%token TPure TContext TGenerated
%token TTypedef TDeclarer TIterator TName TPosition TPosAny
%token<string> TRuleName
%token<Data.clt> Tchar Tshort Tint Tdouble Tfloat Tlong
+%token<Data.clt> Tsize_t Tssize_t Tptrdiff_t
%token<Data.clt> Tvoid Tstruct Tunion Tenum
%token<Data.clt> Tunsigned Tsigned
%token <Parse_aux.idinfo> TMetaIterator TMetaDeclarer
%token <Parse_aux.expinfo> TMetaErr
%token <Parse_aux.info> TMetaParam TMetaStm TMetaStmList TMetaType
-%token <Parse_aux.info> TMetaInit
+%token <Parse_aux.info> TMetaInit TMetaDecl TMetaField
%token <Parse_aux.list_info> TMetaParamList TMetaExpList
%token <Parse_aux.typed_expinfo> TMetaExp TMetaIdExp TMetaLocalIdExp TMetaConst
%token <Parse_aux.pos_info> TMetaPos
%token <Data.clt> TAnd
%token <Data.clt> TEqEq TNotEq TTildeEq TTildeExclEq TSub
%token <Ast_cocci.logicalOp * Data.clt> TLogOp /* TInf TSup TInfEq TSupEq */
-%token <Ast_cocci.arithOp * Data.clt> TShOp /* TShl TShr */
+%token <Ast_cocci.arithOp * Data.clt> TShLOp TShROp /* TShl TShr */
%token <Ast_cocci.arithOp * Data.clt> TDmOp /* TDiv TMod */
%token <Data.clt> TPlus TMinus
%token <Data.clt> TMul TTilde
%left TAnd
%left TEqEq TNotEq
%left TLogOp /* TInf TSup TInfEq TSupEq */
-%left TShOp /* TShl TShr */
+%left TShLOp TShROp /* TShl TShr */
%left TPlus TMinus
%left TMul TDmOp /* TDiv TMod */
%start meta_main
%type <(Ast_cocci.metavar,Ast_cocci.metavar) Common.either list> meta_main
-%start <(string option (*string*) * string option (*ast*)) * Ast_cocci.meta_name * Ast_cocci.metavar> script_meta_main
+%start <(string option (*string*) * string option (*ast*)) * (Ast_cocci.meta_name * Ast_cocci.metavar) option> script_meta_main
%start iso_main
%type <Ast0_cocci.anything list list> iso_main
/* these rules have no name as a cheap way to ensure that no normal
rule inherits their metavariables or depends on them */
{ P.make_generated_rule_name_result None d i a e ee }
- | TScript TDotDot lang=pure_ident d=depends TArob
- { P.make_script_rule_name_result lang d }
+ | TScript TDotDot lang=pure_ident nm=ioption(pure_ident) d=depends TArob
+ { P.make_script_rule_name_result lang nm d }
| TInitialize TDotDot lang=pure_ident d=depends TArob
{ P.make_initial_script_rule_name_result lang d }
| TFinalize TDotDot lang=pure_ident d=depends TArob
!Data.add_pos_meta name constraints any; tok in
P.create_metadec_with_constraints ar false kindfn ids }
| ar=arity ispure=pure
- TParameter Tlist TOCro id=pure_ident_or_meta_ident TCCro
+ TParameter Tlist TOCro len=list_len TCCro
ids=comma_list(pure_ident_or_meta_ident) TMPtVirg
{ P.create_len_metadec ar ispure
(fun lenname arity name pure check_meta ->
- let tok =
- check_meta(Ast.MetaParamListDecl(arity,name,Some lenname)) in
- !Data.add_paramlist_meta name (Some lenname) pure; tok)
- id ids }
+ let tok = check_meta(Ast.MetaParamListDecl(arity,name,lenname)) in
+ !Data.add_paramlist_meta name lenname pure; tok)
+ len ids }
| ar=arity ispure=pure
- TExpression Tlist TOCro id=pure_ident_or_meta_ident TCCro
+ TExpression Tlist TOCro len=list_len TCCro
ids=comma_list(pure_ident_or_meta_ident) TMPtVirg
{ P.create_len_metadec ar ispure
(fun lenname arity name pure check_meta ->
- let tok =
- check_meta(Ast.MetaExpListDecl(arity,name,Some lenname)) in
- !Data.add_explist_meta name (Some lenname) pure; tok)
- id ids }
+ let tok = check_meta(Ast.MetaExpListDecl(arity,name,lenname)) in
+ !Data.add_explist_meta name lenname pure; tok)
+ len ids }
+
+list_len:
+ pure_ident_or_meta_ident { Common.Left $1 }
+| TInt { let (x,clt) = $1 in Common.Right (int_of_string x) }
%inline metakind_fresh:
TFresh TIdentifier
!Data.add_param_meta name pure; tok) }
| TParameter Tlist
{ (fun arity name pure check_meta ->
- let tok = check_meta(Ast.MetaParamListDecl(arity,name,None)) in
- !Data.add_paramlist_meta name None pure; tok) }
+ let len = Ast.AnyLen in
+ let tok = check_meta(Ast.MetaParamListDecl(arity,name,len)) in
+ !Data.add_paramlist_meta name len pure; tok) }
| TExpression Tlist
{ (fun arity name pure check_meta ->
- let tok = check_meta(Ast.MetaExpListDecl(arity,name,None)) in
- !Data.add_explist_meta name None pure; tok) }
+ let len = Ast.AnyLen in
+ let tok = check_meta(Ast.MetaExpListDecl(arity,name,len)) in
+ !Data.add_explist_meta name len pure; tok) }
| TType
{ (fun arity name pure check_meta ->
let tok = check_meta(Ast.MetaTypeDecl(arity,name)) in
{ (fun arity name pure check_meta ->
let tok = check_meta(Ast.MetaStmDecl(arity,name)) in
!Data.add_stm_meta name pure; tok) }
+| TDeclaration
+ { (fun arity name pure check_meta ->
+ let tok = check_meta(Ast.MetaDeclDecl(arity,name)) in
+ !Data.add_decl_meta name pure; tok) }
+| TField
+ { (fun arity name pure check_meta ->
+ let tok = check_meta(Ast.MetaFieldDecl(arity,name)) in
+ !Data.add_field_meta name pure; tok) }
| TStatement Tlist
{ (fun arity name pure check_meta ->
let tok = check_meta(Ast.MetaStmListDecl(arity,name)) in
| Some _ ->
!Data.add_local_idexp_meta ty name constraints pure;
check_meta(Ast.MetaLocalIdExpDecl(arity,name,ty))) }
-| TExpression m=nonempty_list(TMul)
- { (fun arity name pure check_meta constraints ->
- let ty = Some [P.ty_pointerify Type_cocci.Unknown m] in
- let tok = check_meta(Ast.MetaExpDecl(arity,name,ty)) in
- !Data.add_exp_meta ty name constraints pure; tok) }
-| vl=meta_exp_type TOCro TCCro
+| TExpression ty=expression_type
{ (fun arity name pure check_meta constraints ->
- let ty = Some (List.map (function x -> Type_cocci.Array x) vl) in
+ let ty = Some [ty] in
let tok = check_meta(Ast.MetaExpDecl(arity,name,ty)) in
!Data.add_exp_meta ty name constraints pure; tok) }
| TConstant ty=ioption(meta_exp_type)
let tok = check_meta(Ast.MetaConstDecl(arity,name,ty)) in
!Data.add_const_meta ty name constraints pure; tok) }
+expression_type:
+ m=nonempty_list(TMul) { P.ty_pointerify Type_cocci.Unknown m }
+| Tenum m=list(TMul)
+ { P.ty_pointerify (Type_cocci.EnumName Type_cocci.NoName) m }
+| Tstruct m=list(TMul)
+ { P.ty_pointerify
+ (Type_cocci.StructUnionName (Type_cocci.Struct,Type_cocci.NoName)) m }
+| Tunion m=list(TMul)
+ { P.ty_pointerify
+ (Type_cocci.StructUnionName (Type_cocci.Union,Type_cocci.NoName)) m }
+
%inline metakind_atomic_expe:
TExpression
{ (fun arity name pure check_meta constraints ->
!Data.add_exp_meta ty name constraints pure; tok)
}
-
meta_exp_type:
t=typedef_ctype
{ [Ast0_cocci.ast0_type_to_type t] }
+| t=typedef_ctype TOCro TCCro
+ { [Type_cocci.Array (Ast0_cocci.ast0_type_to_type t)] }
| TOBrace t=comma_list(ctype) TCBrace m=list(TMul)
{ List.map
(function x -> P.ty_pointerify (Ast0_cocci.ast0_type_to_type x) m)
{ Ast0.wrap(Ast0.BaseType(Ast.DoubleType,[P.clt2mcode "double" ty])) }
| ty=Tfloat
{ Ast0.wrap(Ast0.BaseType(Ast.FloatType,[P.clt2mcode "float" ty])) }
+| ty=Tsize_t
+ { Ast0.wrap(Ast0.BaseType(Ast.SizeType,[P.clt2mcode "size_t" ty])) }
+| ty=Tssize_t
+ { Ast0.wrap(Ast0.BaseType(Ast.SSizeType,[P.clt2mcode "ssize_t" ty])) }
+| ty=Tptrdiff_t
+ { Ast0.wrap(Ast0.BaseType(Ast.PtrDiffType,[P.clt2mcode "ptrdiff_t" ty])) }
| s=Tenum i=ident
- { Ast0.wrap(Ast0.EnumName(P.clt2mcode "enum" s, i)) }
+ { Ast0.wrap(Ast0.EnumName(P.clt2mcode "enum" s, Some i)) }
+| s=Tenum i=ioption(ident) l=TOBrace ids=enum_decl_list r=TCBrace
+ { (if i = None && !Data.in_iso
+ then failwith "enums must be named in the iso file");
+ Ast0.wrap(Ast0.EnumDef(Ast0.wrap(Ast0.EnumName(P.clt2mcode "enum" s, i)),
+ P.clt2mcode "{" l, ids, P.clt2mcode "}" r)) }
| s=struct_or_union i=ident
{ Ast0.wrap(Ast0.StructUnionName(s, Some i)) }
| s=struct_or_union i=ioption(ident)
| u=Tunion { P.clt2mcode Ast.Union u }
struct_decl:
- TNothing { [] }
+ TNothing { [] }
+ | struct_decl_one { [$1] }
+
+struct_decl_one:
+ | TMetaField { P.meta_field $1 }
| t=ctype d=d_ident pv=TPtVirg
{ let (id,fn) = d in
- [Ast0.wrap(Ast0.UnInit(None,fn t,id,P.clt2mcode ";" pv))] }
+ Ast0.wrap(Ast0.UnInit(None,fn t,id,P.clt2mcode ";" pv)) }
| t=ctype lp1=TOPar st=TMul d=d_ident rp1=TCPar
lp2=TOPar p=decl_list(name_opt_decl) rp2=TCPar pv=TPtVirg
{ let (id,fn) = d in
(Ast0.FunctionPointer
(t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
- [Ast0.wrap(Ast0.UnInit(None,fn t,id,P.clt2mcode ";" pv))] }
+ Ast0.wrap(Ast0.UnInit(None,fn t,id,P.clt2mcode ";" pv)) }
| cv=ioption(const_vol) i=pure_ident d=d_ident pv=TPtVirg
{ let (id,fn) = d in
let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
- [Ast0.wrap(Ast0.UnInit(None,fn idtype,id,P.clt2mcode ";" pv))] }
+ Ast0.wrap(Ast0.UnInit(None,fn idtype,id,P.clt2mcode ";" pv)) }
struct_decl_list:
struct_decl_list_start { Ast0.wrap(Ast0.DOTS($1)) }
struct_decl_list_start:
struct_decl { $1 }
| struct_decl struct_decl_list_start { $1@$2 }
-| d=edots_when(TEllipsis,struct_decl) r=continue_struct_decl_list
- { (P.mkddots "..." d)::r }
+| d=edots_when(TEllipsis,struct_decl_one) r=continue_struct_decl_list
+ { (P.mkddots_one "..." d)::r }
continue_struct_decl_list:
/* empty */ { [] }
| struct_decl { $1 }
+/* ---------------------------------------------------------------------- */
+/* very restricted what kinds of expressions can appear in an enum decl */
+
+enum_decl_one:
+ | ident { Ast0.wrap(Ast0.Ident($1)) }
+ | ident TEq enum_val
+ { let id = Ast0.wrap(Ast0.Ident($1)) in
+ Ast0.wrap
+ (Ast0.Assignment
+ (id,P.clt2mcode Ast.SimpleAssign $2,Ast0.set_arg_exp $3,
+ false)) }
+
+enum_val:
+ ident { Ast0.wrap(Ast0.Ident($1)) }
+ | TInt
+ { let (x,clt) = $1 in
+ Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) }
+ | TMetaConst
+ { let (nm,constraints,pure,ty,clt) = $1 in
+ Ast0.wrap
+ (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.CONST,pure)) }
+ | TMetaExp
+ { let (nm,constraints,pure,ty,clt) = $1 in
+ Ast0.wrap
+ (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ANY,pure)) }
+ | TMetaIdExp
+ { let (nm,constraints,pure,ty,clt) = $1 in
+ Ast0.wrap
+ (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ID,pure)) }
+
+enum_decl_list:
+ nonempty_list_start(enum_decl_one,edots_when(TEllipsis,enum_decl_one))
+ { Ast0.wrap(Ast0.DOTS($1 P.mkedots (fun c -> Ast0.EComma c))) }
+
/*****************************************************************************/
/* have to inline everything to avoid conflicts? switch to proper
/* ---------------------------------------------------------------------- */
-define_param_list: define_param_list_start
- {let circle x =
- match Ast0.unwrap x with Ast0.DPcircles(_) -> true | _ -> false in
- if List.exists circle $1
- then Ast0.wrap(Ast0.CIRCLES($1))
- else Ast0.wrap(Ast0.DOTS($1)) }
-
-define_param_list_start:
- ident { [Ast0.wrap(Ast0.DParam $1)] }
- | ident TComma define_param_list_start
- { Ast0.wrap(Ast0.DParam $1)::
- Ast0.wrap(Ast0.DPComma(P.clt2mcode "," $2))::$3 }
- | d=TEllipsis r=list(dp_comma_args(TEllipsis))
- { (P.mkdpdots "..." d)::
- (List.concat (List.map (function x -> x (P.mkdpdots "...")) r)) }
-
-dp_comma_args(dotter):
- c=TComma d=dotter
- { function dot_builder ->
- [Ast0.wrap(Ast0.DPComma(P.clt2mcode "," c)); dot_builder d] }
-| TComma ident
- { function dot_builder ->
- [Ast0.wrap(Ast0.DPComma(P.clt2mcode "," $1));
- Ast0.wrap(Ast0.DParam $2)] }
-
-define_param_list_option: define_param_list { $1 }
- | /* empty */ { Ast0.wrap(Ast0.DOTS([])) }
+dparam: ident { Ast0.wrap(Ast0.DParam $1) }
+
+define_param_list_option:
+ empty_list_start(dparam,TEllipsis)
+ { Ast0.wrap
+ (Ast0.DOTS
+ ($1
+ (fun _ d -> Ast0.wrap(Ast0.DPdots(P.clt2mcode "," d)))
+ (fun c -> Ast0.DPComma c))) }
/*****************************************************************************/
decl_var:
t=ctype pv=TPtVirg
{ [Ast0.wrap(Ast0.TyDecl(t,P.clt2mcode ";" pv))] }
+ | TMetaDecl { [P.meta_decl $1] }
| s=ioption(storage) t=ctype d=comma_list(d_ident) pv=TPtVirg
{ List.map
(function (id,fn) ->
one_decl_var:
t=ctype pv=TPtVirg
{ Ast0.wrap(Ast0.TyDecl(t,P.clt2mcode ";" pv)) }
+ | TMetaDecl { P.meta_decl $1 }
| s=ioption(storage) t=ctype d=d_ident pv=TPtVirg
{ let (id,fn) = d in
Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)) }
eexpr
{ Ast0.wrap(Ast0.InitExpr($1)) }
| TOBrace initialize_list TCBrace
- { Ast0.wrap(Ast0.InitList(P.clt2mcode "{" $1,$2,P.clt2mcode "}" $3)) }
- | TOBrace TCBrace
- { Ast0.wrap
- (Ast0.InitList(P.clt2mcode "{" $1,Ast0.wrap(Ast0.DOTS []),
- P.clt2mcode "}" $2)) }
+ { if P.struct_initializer $2
+ then
+ let il = P.drop_dot_commas $2 in
+ Ast0.wrap(Ast0.InitList(P.clt2mcode "{" $1,il,P.clt2mcode "}" $3,false))
+ else
+ Ast0.wrap(Ast0.InitList(P.clt2mcode "{" $1,$2,P.clt2mcode "}" $3,true)) }
| TMetaInit
{let (nm,pure,clt) = $1 in
Ast0.wrap(Ast0.MetaInit(P.clt2mcode nm clt,pure)) }
/*dots and nests probably not allowed at top level, haven't looked into why*/
arith_expr(eexpr,invalid) { Ast0.wrap(Ast0.InitExpr($1)) }
| TOBrace initialize_list TCBrace
- { Ast0.wrap(Ast0.InitList(P.clt2mcode "{" $1,$2,P.clt2mcode "}" $3)) }
-| TOBrace TCBrace
- { Ast0.wrap
- (Ast0.InitList(P.clt2mcode "{" $1,Ast0.wrap(Ast0.DOTS []),
- P.clt2mcode "}" $2)) }
+ { if P.struct_initializer $2
+ then
+ let il = P.drop_dot_commas $2 in
+ Ast0.wrap(Ast0.InitList(P.clt2mcode "{" $1,il,P.clt2mcode "}" $3,false))
+ else
+ Ast0.wrap(Ast0.InitList(P.clt2mcode "{" $1,$2,P.clt2mcode "}" $3,true)) }
/* gccext:, labeled elements */
-| list(designator) TEq initialize2
+| list(designator) TEq initialize2 /*can we have another of these on the rhs?*/
{ Ast0.wrap(Ast0.InitGccExt($1,P.clt2mcode "=" $2,$3)) }
| ident TDotDot initialize2
{ Ast0.wrap(Ast0.InitGccName($1,P.clt2mcode ":" $2,$3)) } /* in old kernel */
$4,P.clt2mcode "]" $5) }
initialize_list:
- initialize_list_start { Ast0.wrap(Ast0.DOTS($1)) }
-
-initialize_list_start:
- initialize2 TComma { [$1;Ast0.wrap(Ast0.IComma(P.clt2mcode "," $2))] }
-| initialize2 TComma initialize_list_start
- { $1::Ast0.wrap(Ast0.IComma(P.clt2mcode "," $2))::$3 }
-| TNothing initialize_list_start
- { $2 } /* + code only */
-| d=edots_when(TEllipsis,initialize)
- r=comma_initializers(edots_when(TEllipsis,initialize))
- { (P.mkidots "..." d)::
- (List.concat(List.map (function x -> x (P.mkidots "...")) r)) }
-
-comma_initializers(dotter):
- /* empty */ { [] }
-| d=dotter r=comma_initializers2(dotter)
- { (function dot_builder -> [dot_builder d])::r }
-| TNothing r=comma_initializers(dotter) { r }
-| i=initialize2 c=TComma r=comma_initializers(dotter)
- { (function dot_builder -> [i; Ast0.wrap(Ast0.IComma(P.clt2mcode "," c))])::
- r }
-
-comma_initializers2(dotter):
- /* empty */ { [] }
-| TNothing r=comma_initializers(dotter) { r }
-| i=initialize2 c=TComma r=comma_initializers(dotter)
- { (function dot_builder -> [i; Ast0.wrap(Ast0.IComma(P.clt2mcode "," c))])::
- r }
+ empty_list_start(initialize2,edots_when(TEllipsis,initialize))
+ { Ast0.wrap(Ast0.DOTS($1 P.mkidots (fun c -> Ast0.IComma c))) }
/* a statement that is part of a list */
decl_statement:
{ P.arith_op Ast.Plus $1 $2 $3 }
| arith_expr(r,pe) TMinus arith_expr(r,pe)
{ P.arith_op Ast.Minus $1 $2 $3 }
- | arith_expr(r,pe) TShOp arith_expr(r,pe)
+ | arith_expr(r,pe) TShLOp arith_expr(r,pe)
+ { let (op,clt) = $2 in P.arith_op op $1 clt $3 }
+ | arith_expr(r,pe) TShROp arith_expr(r,pe)
{ let (op,clt) = $2 in P.arith_op op $1 clt $3 }
| arith_expr(r,pe) TLogOp arith_expr(r,pe)
{ let (op,clt) = $2 in P.logic_op op $1 clt $3 }
/*****************************************************************************/
decl_list(decl):
- /* empty */ { Ast0.wrap(Ast0.DOTS([])) }
-| decl_list_start(decl)
- {let circle x =
- match Ast0.unwrap x with Ast0.Pcircles(_) -> true | _ -> false in
- if List.exists circle $1
- then Ast0.wrap(Ast0.CIRCLES($1))
- else Ast0.wrap(Ast0.DOTS($1)) }
-
-decl_list_start(decl):
- one_dec(decl) { [$1] }
-| one_dec(decl) TComma decl_list_start(decl)
- { $1::Ast0.wrap(Ast0.PComma(P.clt2mcode "," $2))::$3 }
-| TEllipsis list(comma_decls(TEllipsis,decl))
- { Ast0.wrap(Ast0.Pdots(P.clt2mcode "..." $1))::
- (List.concat(List.map (function x -> x (P.mkpdots "...")) $2)) }
+ empty_list_start(one_dec(decl),TEllipsis)
+ { Ast0.wrap
+ (Ast0.DOTS
+ ($1
+ (fun _ d -> Ast0.wrap(Ast0.Pdots(P.clt2mcode "..." d)))
+ (fun c -> Ast0.PComma c))) }
one_dec(decl):
decl { $1 }
| TMetaParamList
{ let (nm,lenname,pure,clt) = $1 in
let nm = P.clt2mcode nm clt in
- let lenname =
- match lenname with
- Some nm -> Some(P.clt2mcode nm clt)
- | None -> None in
+ let lenname =
+ match lenname with
+ Ast.AnyLen -> Ast0.AnyListLen
+ | Ast.MetaLen nm -> Ast0.MetaListLen(P.clt2mcode nm clt)
+ | Ast.CstLen n -> Ast0.CstListLen n in
Ast0.wrap(Ast0.MetaParamList(nm,lenname,pure)) }
-comma_decls(dotter,decl):
- TComma dotter
- { function dot_builder ->
- [Ast0.wrap(Ast0.PComma(P.clt2mcode "," $1));
- dot_builder $2] }
-| TComma one_dec(decl)
- { function dot_builder ->
- [Ast0.wrap(Ast0.PComma(P.clt2mcode "," $1)); $2] }
+/* ---------------------------------------------------------------------- */
+/* comma list parser, used for fn params, fn args, enums, initlists,
+ #define params */
+
+/* enums: enum_decl, edots_when(TEllipsis,enum_decl_one)
+fun s d -> P.mkedots "..." d
+fun c -> Ast0.EComma c
+ */
+
+empty_list_start(elem,dotter):
+ /* empty */ { fun build_dots build_comma -> [] }
+| nonempty_list_start(elem,dotter) { $1 }
+
+nonempty_list_start(elem,dotter): /* dots allowed */
+ elem { fun build_dots build_comma -> [$1] }
+| elem TComma
+ { fun build_dots build_comma ->
+ $1::[Ast0.wrap(build_comma(P.clt2mcode "," $2))] }
+| elem TComma nonempty_list_start(elem,dotter)
+ { fun build_dots build_comma ->
+ $1::(Ast0.wrap(build_comma(P.clt2mcode "," $2)))::
+ ($3 build_dots build_comma) }
+| TNothing nonempty_list_start(elem,dotter) { $2 }
+| d=dotter { fun build_dots build_comma -> [(build_dots "..." d)] }
+| d=dotter TComma
+ { fun build_dots build_comma ->
+ [(build_dots "..." d);Ast0.wrap(build_comma(P.clt2mcode "," $2))] }
+| d=dotter TComma r=continue_list(elem,dotter)
+ { fun build_dots build_comma ->
+ (build_dots "..." d)::
+ (Ast0.wrap(build_comma(P.clt2mcode "," $2)))::
+ (r build_dots build_comma) }
+
+continue_list(elem,dotter): /* dots not allowed */
+ elem { fun build_dots build_comma -> [$1] }
+| elem TComma
+ { fun build_dots build_comma ->
+ $1::[Ast0.wrap(build_comma(P.clt2mcode "," $2))] }
+| elem TComma nonempty_list_start(elem,dotter)
+ { fun build_dots build_comma ->
+ $1::(Ast0.wrap(build_comma(P.clt2mcode "," $2)))::
+ ($3 build_dots build_comma) }
+| TNothing nonempty_list_start(elem,dotter) { $2 }
/* ---------------------------------------------------------------------- */
top_init:
TOInit initialize_list TCBrace
- { Ast0.wrap(Ast0.InitList(P.clt2mcode "{" $1,$2,P.clt2mcode "}" $3)) }
+ { if P.struct_initializer $2
+ then
+ let il = P.drop_dot_commas $2 in
+ Ast0.wrap(Ast0.InitList(P.clt2mcode "{" $1,il,P.clt2mcode "}" $3,false))
+ else
+ Ast0.wrap(Ast0.InitList(P.clt2mcode "{" $1,$2,P.clt2mcode "}" $3,true)) }
/* ------------------------------------------------------------------------ */
/* Plus top level */
/* ---------------------------------------------------------------------- */
-eexpr_list:
- eexpr_list_start
- {let circle x =
- match Ast0.unwrap x with Ast0.Ecircles(_) -> true | _ -> false in
- let star x =
- match Ast0.unwrap x with Ast0.Estars(_) -> true | _ -> false in
- if List.exists circle $1
- then Ast0.wrap(Ast0.CIRCLES($1))
- else
- if List.exists star $1
- then Ast0.wrap(Ast0.STARS($1))
- else Ast0.wrap(Ast0.DOTS($1)) }
-
/* arg expr. may contain a type or a explist metavariable */
aexpr:
- eexpr
- { Ast0.set_arg_exp $1 }
+ dexpr { Ast0.set_arg_exp $1 }
| TMetaExpList
{ let (nm,lenname,pure,clt) = $1 in
let nm = P.clt2mcode nm clt in
let lenname =
match lenname with
- Some nm -> Some(P.clt2mcode nm clt)
- | None -> None in
+ Ast.AnyLen -> Ast0.AnyListLen
+ | Ast.MetaLen nm -> Ast0.MetaListLen(P.clt2mcode nm clt)
+ | Ast.CstLen n -> Ast0.CstListLen n in
Ast0.wrap(Ast0.MetaExprList(nm,lenname,pure)) }
| ctype
{ Ast0.set_arg_exp(Ast0.wrap(Ast0.TypeExp($1))) }
-eexpr_list_start:
- aexpr { [$1] }
- | aexpr TComma eexpr_list_start
- { $1::Ast0.wrap(Ast0.EComma(P.clt2mcode "," $2))::$3 }
-
-comma_args(dotter):
- c=TComma d=dotter
- { function dot_builder ->
- [Ast0.wrap(Ast0.EComma(P.clt2mcode "," c)); dot_builder d] }
-| TComma aexpr
- { function dot_builder ->
- [Ast0.wrap(Ast0.EComma(P.clt2mcode "," $1)); $2] }
-
-eexpr_list_option: eexpr_list { $1 }
- | /* empty */ { Ast0.wrap(Ast0.DOTS([])) }
+eexpr_list_option:
+ empty_list_start(aexpr,TEllipsis)
+ { Ast0.wrap
+ (Ast0.DOTS
+ ($1
+ (fun _ d -> Ast0.wrap(Ast0.Edots(P.clt2mcode "..." d,None)))
+ (fun c -> Ast0.EComma c))) }
/****************************************************************************/
| TScriptData { () }
script_meta_main:
- py=pure_ident script_name_decl
- { let (nm,mv) = $2 in
- ((Some (P.id2name py), None), nm, mv) }
- | TOPar TUnderscore TComma ast=pure_ident TCPar script_name_decl
- { let (nm,mv) = $6 in
- ((None, Some (P.id2name ast)), nm, mv) }
- | TOPar str=pure_ident TComma TUnderscore TCPar script_name_decl
- { let (nm,mv) = $6 in
- ((Some (P.id2name str), None), nm, mv) }
- | TOPar str=pure_ident TComma ast=pure_ident TCPar script_name_decl
- { let (nm,mv) = $6 in
- ((Some (P.id2name str), Some (P.id2name ast)), nm, mv) }
+ py=pure_ident TMPtVirg
+ { ((Some (P.id2name py), None), None) }
+ | py=pure_ident script_name_decl TMPtVirg
+ { ((Some (P.id2name py), None), Some $2) }
+ | TOPar TUnderscore TComma ast=pure_ident TCPar script_name_decl TMPtVirg
+ { ((None, Some (P.id2name ast)), Some $6) }
+ | TOPar str=pure_ident TComma TUnderscore TCPar script_name_decl TMPtVirg
+ { ((Some (P.id2name str), None), Some $6) }
+ | TOPar str=pure_ident TComma ast=pure_ident TCPar script_name_decl TMPtVirg
+ { ((Some (P.id2name str), Some (P.id2name ast)), Some $6) }
script_name_decl:
- TShOp TRuleName TDot cocci=pure_ident TMPtVirg
+ TShLOp TRuleName TDot cocci=pure_ident
{ let nm = P.id2name cocci in
let mv = Parse_aux.lookup $2 nm in
(($2, nm), mv) }
- | TShOp TVirtual TDot cocci=pure_ident TMPtVirg
+ | TShLOp TVirtual TDot cocci=pure_ident
{ let nm = P.id2name cocci in
let name = ("virtual", nm) in
let mv = Ast.MetaIdDecl(Ast.NONE,name) in
- (name,mv) }
+ (name,mv) }