module Ast0 = Ast0_cocci
module Ast = Ast_cocci
module P = Parse_aux
+
+(* ---------------------------------------------------------------------- *)
+(* support for TMeta *)
+
+let print_meta (r,n) = r^"."^n
+
+let meta_metatable = Hashtbl.create(101)
+
+let coerce_tmeta newty name builder matcher =
+ try
+ let x = Hashtbl.find meta_metatable name in
+ if not (matcher x)
+ then
+ failwith
+ (Printf.sprintf "Metavariable %s is used as %s"
+ (print_meta name) newty)
+ with Not_found ->
+ (if !Flag_parsing_cocci.show_SP
+ then
+ Common.pr2
+ (Printf.sprintf
+ "Metavariable %s is assumed to be %s metavariable"
+ (print_meta name) newty));
+ Hashtbl.add meta_metatable name builder
+
+let tmeta_to_type (name,pure,clt) =
+ (coerce_tmeta "a type" name (TMetaType(name,pure,clt))
+ (function TMetaType(_,_,_) -> true | _ -> false));
+ Ast0.wrap(Ast0.MetaType(P.clt2mcode name clt,pure))
+
+let tmeta_to_field (name,pure,clt) =
+ (coerce_tmeta "a field" name (TMetaField(name,pure,clt))
+ (function TMetaField(_,_,_) -> true | _ -> false));
+ P.meta_field (name,pure,clt)
+
+let tmeta_to_exp (name,pure,clt) =
+ (coerce_tmeta "an expression" name
+ (TMetaExp(name,Ast0.NoConstraint,pure,None,clt))
+ (function TMetaExp(_,_,_,_,_) -> true | _ -> false));
+ Ast0.wrap
+ (Ast0.MetaExpr(P.clt2mcode name clt,Ast0.NoConstraint,None,Ast.ANY,pure))
+
+let tmeta_to_param (name,pure,clt) =
+ (coerce_tmeta "a parameter" name (TMetaParam(name,pure,clt))
+ (function TMetaParam(_,_,_) -> true | _ -> false));
+ Ast0.wrap(Ast0.MetaParam(P.clt2mcode name clt,pure))
+
+let tmeta_to_statement (name,pure,clt) =
+ (coerce_tmeta "a statement" name (TMetaType(name,pure,clt))
+ (function TMetaType(_,_,_) -> true | _ -> false));
+ P.meta_stm (name,pure,clt)
+
+let tmeta_to_seed_id (name,pure,clt) =
+ (coerce_tmeta "an identifier" name
+ (TMetaId(name,Ast.IdNoConstraint,Ast.NoVal,pure,clt))
+ (function TMetaId(_,_,_,_,_) -> true | _ -> false));
+ Ast.SeedId name
+
+let tmeta_to_ident (name,pure,clt) =
+ (coerce_tmeta "an identifier" name
+ (TMetaId(name,Ast.IdNoConstraint,Ast.NoVal,pure,clt))
+ (function TMetaId(_,_,_,_,_) -> true | _ -> false));
+ Ast0.wrap(Ast0.MetaId(P.clt2mcode name clt,Ast.IdNoConstraint,Ast.NoVal,pure))
%}
%token EOF
%token TIdentifier TExpression TStatement TFunction TLocal TType TParameter
-%token TIdExpression TInitialiser
+%token TIdExpression TInitialiser TDeclaration TField TMetavariable
%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 <string * Data.clt> TIdent TTypeId TDeclarerId TIteratorId
%token <Ast_cocci.added_string * Data.clt> TPragma
-%token <Parse_aux.idinfo> TMetaId TMetaFunc TMetaLocalFunc
+%token <Parse_aux.midinfo> TMetaId
+%token <Parse_aux.idinfo> TMetaFunc TMetaLocalFunc
%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.list_info> TMetaParamList TMetaExpList
+%token <Parse_aux.info> TMetaInit TMetaDecl TMetaField TMeta
+%token <Parse_aux.list_info> TMetaParamList TMetaExpList TMetaInitList
+%token <Parse_aux.list_info> TMetaFieldList
%token <Parse_aux.typed_expinfo> TMetaExp TMetaIdExp TMetaLocalIdExp TMetaConst
%token <Parse_aux.pos_info> TMetaPos
%token <string> TPathIsoFile
%token <string * Data.clt> TIncludeL TIncludeNL
-%token <Data.clt * token> TDefine
+%token <Data.clt * token> TDefine TUndef
%token <Data.clt * token * int * int> TDefineParam
%token <string * Data.clt> TMinusFile TPlusFile
%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
| TUsing TPathIsoFile { Data.Iso(Common.Right $2) }
| TVirtual comma_list(pure_ident)
{ let names = List.map P.id2name $2 in
+ Iteration.parsed_virtual_rules :=
+ Common.union_set names !Iteration.parsed_virtual_rules;
(* ensure that the names of virtual and real rules don't overlap *)
List.iter
(function name -> Hashtbl.add Data.all_metadecls name [])
let tok = check_meta(Ast.MetaExpListDecl(arity,name,lenname)) in
!Data.add_explist_meta name lenname pure; tok)
len ids }
+| ar=arity ispure=pure
+ TField 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.MetaFieldListDecl(arity,name,lenname)) in
+ !Data.add_field_list_meta name lenname pure; tok)
+ len ids }
+| ar=arity ispure=pure
+ TInitialiser 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.MetaInitListDecl(arity,name,lenname)) in
+ !Data.add_initlist_meta name lenname pure; tok)
+ len ids }
list_len:
pure_ident_or_meta_ident { Common.Left $1 }
TFresh TIdentifier
{ (fun name check_meta seed ->
let tok = check_meta(Ast.MetaFreshIdDecl(name,seed)) in
- !Data.add_fresh_id_meta name; tok) }
+ !Data.add_fresh_id_meta name seed; tok) }
/* metavariable kinds with no constraints, etc */
%inline metakind:
- TParameter
+ TMetavariable
+ { (fun arity name pure check_meta ->
+ let tok = check_meta(Ast.MetaMetaDecl(arity,name)) in
+ !Data.add_meta_meta name pure; tok) }
+| TParameter
{ (fun arity name pure check_meta ->
let tok = check_meta(Ast.MetaParamDecl(arity,name)) in
!Data.add_param_meta name pure; tok) }
{ (fun arity name pure check_meta ->
let tok = check_meta(Ast.MetaInitDecl(arity,name)) in
!Data.add_init_meta name pure; tok) }
+| TInitialiser Tlist
+ { (fun arity name pure check_meta ->
+ let len = Ast.AnyLen in
+ let tok = check_meta(Ast.MetaInitListDecl(arity,name,len)) in
+ !Data.add_initlist_meta name len pure; tok) }
| TStatement
{ (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) }
+| TField Tlist
+ { (fun arity name pure check_meta ->
+ let len = Ast.AnyLen in
+ let tok = check_meta(Ast.MetaFieldListDecl(arity,name,len)) in
+ !Data.add_field_list_meta name len pure; tok) }
| TStatement Tlist
{ (fun arity name pure check_meta ->
let tok = check_meta(Ast.MetaStmListDecl(arity,name)) in
let vl = List.assoc name virtual_env in
!Data.add_virt_id_meta_found name vl; []
with Not_found ->
+ Iteration.parsed_virtual_identifiers :=
+ Common.union_set [name]
+ !Iteration.parsed_virtual_identifiers;
let name = ("virtual",name) in
let tok = check_meta(Ast.MetaIdDecl(arity,name)) in
!Data.add_virt_id_meta_not_found name pure; tok 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)) }
-| s=struct_or_union i=ident
+ { 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=type_ident // allow typedef name
{ Ast0.wrap(Ast0.StructUnionName(s, Some i)) }
-| s=struct_or_union i=ioption(ident)
+| s=struct_or_union i=ioption(type_ident)
l=TOBrace d=struct_decl_list r=TCBrace
{ (if i = None && !Data.in_iso
then failwith "structures must be named in the iso file");
Ast0.wrap
(Ast0.DisjType(P.clt2mcode "(" lp,code,mids, P.clt2mcode ")" rp)) }
+mctype:
+| TMeta { tmeta_to_type $1 }
+| ctype {$1}
+
/* signed, unsigned alone not allowed */
typedef_ctype:
cv=ioption(const_vol) ty=all_basic_types m=list(TMul)
{ P.pointerify (P.make_cv cv ty) m }
-| lp=TOPar0 t=midzero_list(ctype,ctype) rp=TCPar0
+| lp=TOPar0 t=midzero_list(mctype,mctype) rp=TCPar0
{ let (mids,code) = t in
Ast0.wrap
(Ast0.DisjType(P.clt2mcode "(" lp,code,mids, P.clt2mcode ")" rp)) }
+| TMeta { tmeta_to_type $1 }
/* ---------------------------------------------------------------------- */
| u=Tunion { P.clt2mcode Ast.Union u }
struct_decl:
- TNothing { [] }
+ TNothing { [] }
+ | struct_decl_one { [$1] }
+
+struct_decl_one:
+ | TMetaField { P.meta_field $1 }
+ | TMetaFieldList { P.meta_field_list $1 }
+ | TMeta { tmeta_to_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:
+ | disj_ident { Ast0.wrap(Ast0.Ident($1)) }
+ | disj_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)) }
+ | TMeta { tmeta_to_exp $1 }
+ | 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
/*ew=loption(error_words)*/
{ match f@b(*@ew*) with
[] -> raise (Semantic_cocci.Semantic "minus slice can't be empty")
- | code -> Top_level.top_level code }
+ | code -> code }
plus_body:
f=loption(filespec)
b=loption(plus_start)
/*ew=loption(error_words)*/
- { Top_level.top_level (f@b(*@ew*)) }
+ { f@b(*@ew*) }
minus_exp_body:
f=loption(filespec)
/*ew=loption(error_words)*/
{ match f@[b](*@ew*) with
[] -> raise (Semantic_cocci.Semantic "minus slice can't be empty")
- | code -> Top_level.top_level code }
+ | code -> code }
plus_exp_body:
f=loption(filespec)
b=top_eexpr
/*ew=loption(error_words)*/
- { Top_level.top_level (f@[b](*@ew*)) }
+ { f@[b](*@ew*) }
filespec:
TMinusFile TPlusFile
P.clt2mcode
(Ast.NonLocal (Parse_aux.str2inc (P.id2name $1)))
(P.drop_bef clt))) }
+| TUndef TLineEnd
+ { let (clt,ident) = $1 in
+ let aft = P.get_aft clt in (* move stuff after the define to the ident *)
+ Ast0.wrap
+ (Ast0.Undef
+ (P.clt2mcode "#undef" (P.drop_aft clt),
+ (match ident with
+ TMetaId((nm,constraints,seed,pure,clt)) ->
+ let clt = P.set_aft aft clt in
+ Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,seed,pure))
+ | TIdent((nm,clt)) ->
+ let clt = P.set_aft aft clt in
+ Ast0.wrap(Ast0.Id(P.clt2mcode nm clt))
+ | _ ->
+ raise
+ (Semantic_cocci.Semantic
+ "unexpected name for a #define")))) }
| d=defineop TLineEnd
{ d (Ast0.wrap(Ast0.DOTS([]))) }
| d=defineop t=ctype TLineEnd
defineop:
TDefine
{ let (clt,ident) = $1 in
+ let aft = P.get_aft clt in (* move stuff after the define to the ident *)
function body ->
Ast0.wrap
(Ast0.Define
- (P.clt2mcode "#define" clt,
+ (P.clt2mcode "#define" (P.drop_aft clt),
(match ident with
- TMetaId((nm,constraints,pure,clt)) ->
- Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure))
- | TIdent(nm_pure) ->
- Ast0.wrap(Ast0.Id(P.id2mcode nm_pure))
+ TMetaId((nm,constraints,seed,pure,clt)) ->
+ let clt = P.set_aft aft clt in
+ Ast0.wrap
+ (Ast0.MetaId(P.clt2mcode nm clt,constraints,seed,pure))
+ | TIdent((nm,clt)) ->
+ let clt = P.set_aft aft clt in
+ Ast0.wrap(Ast0.Id(P.clt2mcode nm clt))
| _ ->
raise
(Semantic_cocci.Semantic
body)) }
| TDefineParam define_param_list_option TCPar
{ let (clt,ident,parenoff,parencol) = $1 in
+ let aft = P.get_aft clt in (* move stuff after the define to the ( *)
(* clt is the start of the #define itself *)
let (arity,line,lline,offset,col,strbef,straft,pos) = clt in
let lp =
P.clt2mcode "("
- (arity,line,lline,parenoff,parencol,[],[],Ast0.NoMetaPos) in
+ (arity,line,lline,parenoff,parencol,[],[],[]) in
function body ->
Ast0.wrap
(Ast0.Define
- (P.clt2mcode "#define" clt,
+ (P.clt2mcode "#define" (P.drop_aft clt),
(match ident with
- TMetaId((nm,constraints,pure,clt)) ->
- Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure))
- | TIdent(nm_pure) ->
- Ast0.wrap(Ast0.Id(P.id2mcode nm_pure))
+ TMetaId((nm,constraints,seed,pure,clt)) ->
+ Ast0.wrap
+ (Ast0.MetaId(P.clt2mcode nm clt,constraints,seed,pure))
+ | TIdent((nm,clt)) ->
+ Ast0.wrap(Ast0.Id(P.clt2mcode nm clt))
| _ ->
raise
(Semantic_cocci.Semantic
"unexpected name for a #define")),
- Ast0.wrap (Ast0.DParams (lp,$2,P.clt2mcode ")" $3)),body)) }
+ (let clt = P.set_aft aft $3 in
+ Ast0.wrap (Ast0.DParams (lp,$2,P.clt2mcode ")" clt))),body)) }
/* ---------------------------------------------------------------------- */
-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: mident { 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))) }
/*****************************************************************************/
funproto:
s=ioption(storage) t=ctype
- id=func_ident lp=TOPar d=decl_list(name_opt_decl) rp=TCPar pt=TPtVirg
+ id=fn_ident lp=TOPar d=decl_list(name_opt_decl) rp=TCPar pt=TPtVirg
{ Ast0.wrap
(Ast0.UnInit
(s,
fundecl:
f=fninfo
- TFunDecl i=func_ident lp=TOPar d=decl_list(decl) rp=TCPar
+ TFunDecl i=fn_ident lp=TOPar d=decl_list(decl) rp=TCPar
lb=TOBrace b=fun_start rb=TCBrace
{ P.verify_parameter_declarations (Ast0.undots d);
Ast0.wrap(Ast0.FunDecl((Ast0.default_info(),Ast0.context_befaft()),
| s=Tregister { P.clt2mcode Ast.Register s }
| s=Textern { P.clt2mcode Ast.Extern s }
-decl: t=ctype i=ident
- { Ast0.wrap(Ast0.Param(t, Some i)) }
+decl: t=ctype i=disj_ident a=list(array_dec)
+ { let t = P.arrayify t a in Ast0.wrap(Ast0.Param(t, Some i)) }
| t=ctype { (*verify in FunDecl*) Ast0.wrap(Ast0.Param(t, None)) }
- | t=ctype lp=TOPar s=TMul i=ident rp=TCPar
+ | t=ctype lp=TOPar s=TMul i=disj_ident rp=TCPar
lp1=TOPar d=decl_list(name_opt_decl) rp1=TCPar
{ let fnptr =
Ast0.wrap
| TMetaParam
{ let (nm,pure,clt) = $1 in
Ast0.wrap(Ast0.MetaParam(P.clt2mcode nm clt,pure)) }
+ | TMeta { tmeta_to_param $1 }
name_opt_decl:
decl { $1 }
statement:
includes { $1 } /* shouldn't be allowed to be a single_statement... */
+| TMeta { tmeta_to_statement $1}
| TMetaStm
{ P.meta_stm $1 }
-| expr TPtVirg
+| option(expr) TPtVirg
{ P.exp_stm $1 $2 }
| TIf TOPar eexpr TCPar single_statement %prec TIf
{ P.ifthen $1 $2 $3 $4 $5 }
| TReturn TPtVirg { P.ret $1 $2 }
| TBreak TPtVirg { P.break $1 $2 }
| TContinue TPtVirg { P.cont $1 $2 }
-| ident TDotDot { P.label $1 $2 }
-| TGoto ident TPtVirg { P.goto $1 $2 $3 }
+| mident TDotDot { P.label $1 $2 }
+| TGoto disj_ident TPtVirg { P.goto $1 $2 $3 }
| TOBrace fun_start TCBrace
{ P.seq $1 $2 $3 }
rule_elem_statement:
one_decl_var
{ Ast0.wrap(Ast0.Decl((Ast0.default_info(),Ast0.context_befaft()),$1)) }
-| expr TPtVirg { P.exp_stm $1 $2 }
+| option(expr) TPtVirg { P.exp_stm $1 $2 }
| TReturn eexpr TPtVirg { P.ret_exp $1 $2 $3 }
| TReturn TPtVirg { P.ret $1 $2 }
| TBreak TPtVirg { P.break $1 $2 }
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)) }
d_ident:
- ident list(array_dec)
- { ($1,
- function t ->
- List.fold_right
- (function (l,i,r) ->
- function rest ->
- Ast0.wrap
- (Ast0.Array(rest,P.clt2mcode "[" l,i,P.clt2mcode "]" r)))
- $2 t) }
+ disj_ident list(array_dec)
+ { ($1, function t -> P.arrayify t $2) }
array_dec: l=TOCro i=option(eexpr) r=TCCro { (l,i,r) }
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
+| mident TDotDot initialize2
{ Ast0.wrap(Ast0.InitGccName($1,P.clt2mcode ":" $2,$3)) } /* in old kernel */
+ | TMetaInit
+ {let (nm,pure,clt) = $1 in
+ Ast0.wrap(Ast0.MetaInit(P.clt2mcode nm clt,pure)) }
+ | TMetaInitList
+ {let (nm,lenname,pure,clt) = $1 in
+ let nm = P.clt2mcode nm clt 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.MetaInitList(nm,lenname,pure)) }
designator:
- | TDot ident
+ | TDot disj_ident
{ Ast0.DesignatorField (P.clt2mcode "." $1,$2) }
| TOCro eexpr TCCro
{ Ast0.DesignatorIndex (P.clt2mcode "[" $1,$2,P.clt2mcode "]" $3) }
$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:
/*****************************************************************************/
-/* The following cannot contain <... ...> at the top level. This can only
-be allowed as an expression when the expression is delimited on both sides
-by expression-specific markers. In that case, the rule eexpr is used, which
+/* expr cannot contain <... ...> at the top level. This can only
+be allowed as an expression when the expression is delimited on the left
+by an expression-specific marker. In that case, the rule eexpr is used, which
allows <... ...> anywhere. Hopefully, this will not be too much of a problem
-in practice. */
+in practice.
+dot_expressions is the most permissive. all three kinds of expressions use
+this once an expression_specific token has been seen */
expr: basic_expr(expr,invalid) { $1 }
/* allows ... and nests */
eexpr: basic_expr(eexpr,dot_expressions) { $1 }
{ Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<+..." $1,
Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
P.clt2mcode "...+>" c, None, true)) }
+| TMeta { tmeta_to_exp $1 }
//whenexp: TWhen TNotEq w=eexpr TLineEnd { w }
basic_expr(recurser,primary_extra):
- assign_expr(recurser,primary_extra) { $1 }
+ assign_expr(recurser,primary_extra) { $1 }
assign_expr(r,pe):
cond_expr(r,pe) { $1 }
cond_expr(r,pe):
arith_expr(r,pe) { $1 }
- | l=arith_expr(r,pe) w=TWhy t=option(eexpr) dd=TDotDot r=cond_expr(r,pe)
+ | l=arith_expr(r,pe) w=TWhy t=option(eexpr) dd=TDotDot r=eexpr/*see parser_c*/
{ Ast0.wrap(Ast0.CondExpr (l, P.clt2mcode "?" w, t,
P.clt2mcode ":" dd, r)) }
arith_expr(r,pe):
cast_expr(r,pe) { $1 }
- | arith_expr(r,pe) TMul arith_expr(r,pe)
+ | arith_expr(r,pe) TMul arith_expr_bis
{ P.arith_op Ast.Mul $1 $2 $3 }
- | arith_expr(r,pe) TDmOp arith_expr(r,pe)
+ | arith_expr(r,pe) TDmOp arith_expr_bis
{ let (op,clt) = $2 in P.arith_op op $1 clt $3 }
- | arith_expr(r,pe) TPlus arith_expr(r,pe)
+ | arith_expr(r,pe) TPlus arith_expr_bis
{ P.arith_op Ast.Plus $1 $2 $3 }
- | arith_expr(r,pe) TMinus arith_expr(r,pe)
+ | arith_expr(r,pe) TMinus arith_expr_bis
{ P.arith_op Ast.Minus $1 $2 $3 }
- | arith_expr(r,pe) TShOp arith_expr(r,pe)
+ | arith_expr(r,pe) TShLOp arith_expr_bis
+ { let (op,clt) = $2 in P.arith_op op $1 clt $3 }
+ | arith_expr(r,pe) TShROp arith_expr_bis
{ let (op,clt) = $2 in P.arith_op op $1 clt $3 }
- | arith_expr(r,pe) TLogOp arith_expr(r,pe)
+ | arith_expr(r,pe) TLogOp arith_expr_bis
{ let (op,clt) = $2 in P.logic_op op $1 clt $3 }
- | arith_expr(r,pe) TEqEq arith_expr(r,pe)
+ | arith_expr(r,pe) TEqEq arith_expr_bis
{ P.logic_op Ast.Eq $1 $2 $3 }
- | arith_expr(r,pe) TNotEq arith_expr(r,pe)
+ | arith_expr(r,pe) TNotEq arith_expr_bis
{ P.logic_op Ast.NotEq $1 $2 $3 }
- | arith_expr(r,pe) TAnd arith_expr(r,pe)
+ | arith_expr(r,pe) TAnd arith_expr_bis
{ P.arith_op Ast.And $1 $2 $3 }
- | arith_expr(r,pe) TOr arith_expr(r,pe)
+ | arith_expr(r,pe) TOr arith_expr_bis
{ P.arith_op Ast.Or $1 $2 $3 }
- | arith_expr(r,pe) TXor arith_expr(r,pe)
+ | arith_expr(r,pe) TXor arith_expr_bis
{ P.arith_op Ast.Xor $1 $2 $3 }
- | arith_expr(r,pe) TAndLog arith_expr(r,pe)
+ | arith_expr(r,pe) TAndLog arith_expr_bis
{ P.logic_op Ast.AndLog $1 $2 $3 }
- | arith_expr(r,pe) TOrLog arith_expr(r,pe)
+ | arith_expr(r,pe) TOrLog arith_expr_bis
{ P.logic_op Ast.OrLog $1 $2 $3 }
+// allows dots now that an expression-specific token has been seen
+// need an extra rule because of recursion restrictions
+arith_expr_bis:
+ cast_expr(eexpr,dot_expressions) { $1 }
+ | arith_expr_bis TMul arith_expr_bis
+ { P.arith_op Ast.Mul $1 $2 $3 }
+ | arith_expr_bis TDmOp arith_expr_bis
+ { let (op,clt) = $2 in P.arith_op op $1 clt $3 }
+ | arith_expr_bis TPlus arith_expr_bis
+ { P.arith_op Ast.Plus $1 $2 $3 }
+ | arith_expr_bis TMinus arith_expr_bis
+ { P.arith_op Ast.Minus $1 $2 $3 }
+ | arith_expr_bis TShLOp arith_expr_bis
+ { let (op,clt) = $2 in P.arith_op op $1 clt $3 }
+ | arith_expr_bis TShROp arith_expr_bis
+ { let (op,clt) = $2 in P.arith_op op $1 clt $3 }
+ | arith_expr_bis TLogOp arith_expr_bis
+ { let (op,clt) = $2 in P.logic_op op $1 clt $3 }
+ | arith_expr_bis TEqEq arith_expr_bis
+ { P.logic_op Ast.Eq $1 $2 $3 }
+ | arith_expr_bis TNotEq arith_expr_bis
+ { P.logic_op Ast.NotEq $1 $2 $3 }
+ | arith_expr_bis TAnd arith_expr_bis
+ { P.arith_op Ast.And $1 $2 $3 }
+ | arith_expr_bis TOr arith_expr_bis
+ { P.arith_op Ast.Or $1 $2 $3 }
+ | arith_expr_bis TXor arith_expr_bis
+ { P.arith_op Ast.Xor $1 $2 $3 }
+ | arith_expr_bis TAndLog arith_expr_bis
+ { P.logic_op Ast.AndLog $1 $2 $3 }
+// no OrLog because it is left associative and this is for
+// a right argument, not sure why not the same problem for AndLog
+
cast_expr(r,pe):
unary_expr(r,pe) { $1 }
| lp=TOPar t=ctype rp=TCPar e=cast_expr(r,pe)
unary_expr(r,pe):
postfix_expr(r,pe) { $1 }
- | TInc unary_expr(r,pe)
+ | TInc unary_expr_bis
{ Ast0.wrap(Ast0.Infix ($2, P.clt2mcode Ast.Inc $1)) }
- | TDec unary_expr(r,pe)
+ | TDec unary_expr_bis
{ Ast0.wrap(Ast0.Infix ($2, P.clt2mcode Ast.Dec $1)) }
| unary_op cast_expr(r,pe)
{ let mcode = $1 in Ast0.wrap(Ast0.Unary($2, mcode)) }
- | TBang unary_expr(r,pe)
+ | TBang unary_expr_bis
{ let mcode = P.clt2mcode Ast.Not $1 in
Ast0.wrap(Ast0.Unary($2, mcode)) }
- | TSizeof unary_expr(r,pe)
+ | TSizeof unary_expr_bis
+ { Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" $1, $2)) }
+ | s=TSizeof lp=TOPar t=ctype rp=TCPar
+ { Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s,
+ P.clt2mcode "(" lp,t,
+ P.clt2mcode ")" rp)) }
+
+// version that allows dots
+unary_expr_bis:
+ postfix_expr(eexpr,dot_expressions) { $1 }
+ | TInc unary_expr_bis
+ { Ast0.wrap(Ast0.Infix ($2, P.clt2mcode Ast.Inc $1)) }
+ | TDec unary_expr_bis
+ { Ast0.wrap(Ast0.Infix ($2, P.clt2mcode Ast.Dec $1)) }
+ | unary_op cast_expr(eexpr,dot_expressions)
+ { let mcode = $1 in Ast0.wrap(Ast0.Unary($2, mcode)) }
+ | TBang unary_expr_bis
+ { let mcode = P.clt2mcode Ast.Not $1 in
+ Ast0.wrap(Ast0.Unary($2, mcode)) }
+ | TSizeof unary_expr_bis
{ Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" $1, $2)) }
| s=TSizeof lp=TOPar t=ctype rp=TCPar
{ Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s,
| postfix_expr(r,pe) TOCro eexpr TCCro
{ Ast0.wrap(Ast0.ArrayAccess ($1,P.clt2mcode "[" $2,$3,
P.clt2mcode "]" $4)) }
- | postfix_expr(r,pe) TDot ident
+ | postfix_expr(r,pe) TDot disj_ident
{ Ast0.wrap(Ast0.RecordAccess($1, P.clt2mcode "." $2, $3)) }
- | postfix_expr(r,pe) TPtrOp ident
+ | postfix_expr(r,pe) TPtrOp disj_ident
{ Ast0.wrap(Ast0.RecordPtAccess($1, P.clt2mcode "->" $2,
$3)) }
| postfix_expr(r,pe) TInc
primary_expr(recurser,primary_extra):
func_ident { Ast0.wrap(Ast0.Ident($1)) }
+ | TAndLog ident
+ { let op = P.clt2mcode Ast.GetRefLabel $1 in
+ Ast0.wrap(Ast0.Unary(Ast0.wrap(Ast0.Ident($2)), op)) }
| TInt
{ let (x,clt) = $1 in
Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) }
seed_elem:
TString { let (x,_) = $1 in Ast.SeedString x }
-| TMetaId { let (x,_,_,_) = $1 in Ast.SeedId x }
+| TMetaId { let (x,_,_,_,_) = $1 in Ast.SeedId x }
+| TMeta {failwith "tmeta"}
+| TVirtual TDot pure_ident
+ { let nm = ("virtual",P.id2name $3) in
+ Iteration.parsed_virtual_identifiers :=
+ Common.union_set [snd nm]
+ !Iteration.parsed_virtual_identifiers;
+ try Ast.SeedString (List.assoc (snd nm) !Flag.defined_virtual_env)
+ with Not_found -> Ast.SeedId nm }
| TRuleName TDot pure_ident
{ let nm = ($1,P.id2name $3) in
P.check_meta(Ast.MetaIdDecl(Ast.NONE,nm));
None -> (i, Ast.IdNoConstraint)
| Some constraint_ -> (i,constraint_))
}
-| TVirtual TDot pure_ident { Common.Right (P.id2name $3) }
+| TVirtual TDot pure_ident
+ {
+ let nm = P.id2name $3 in
+ Iteration.parsed_virtual_identifiers :=
+ Common.union_set [nm]
+ !Iteration.parsed_virtual_identifiers;
+ Common.Right nm
+ }
pure_ident_or_meta_ident_with_idconstraint(constraint_type):
i=pure_ident_or_meta_ident c=option(constraint_type)
(function mv -> Ast.MetaPosDecl(Ast.NONE,mv)))
l }
-func_ident: pure_ident
- { Ast0.wrap(Ast0.Id(P.id2mcode $1)) }
- | TMetaId
+func_ident:
+ ident { $1 }
+ | TMetaFunc
{ let (nm,constraints,pure,clt) = $1 in
- Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) }
+ Ast0.wrap(Ast0.MetaFunc(P.clt2mcode nm clt,constraints,pure)) }
+ | TMetaLocalFunc
+ { let (nm,constraints,pure,clt) = $1 in
+ Ast0.wrap
+ (Ast0.MetaLocalFunc(P.clt2mcode nm clt,constraints,pure)) }
+
+fn_ident: disj_ident { $1 }
| TMetaFunc
{ let (nm,constraints,pure,clt) = $1 in
Ast0.wrap(Ast0.MetaFunc(P.clt2mcode nm clt,constraints,pure)) }
ident: pure_ident
{ Ast0.wrap(Ast0.Id(P.id2mcode $1)) }
| TMetaId
- { let (nm,constraints,pure,clt) = $1 in
- Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) }
+ { let (nm,constraints,seed,pure,clt) = $1 in
+ Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,seed,pure)) }
+
+mident: pure_ident
+ { Ast0.wrap(Ast0.Id(P.id2mcode $1)) }
+ | TMeta { tmeta_to_ident $1 }
+ | TMetaId
+ { let (nm,constraints,seed,pure,clt) = $1 in
+ Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,seed,pure)) }
+
+disj_ident:
+ mident { $1 }
+ | lp=TOPar0 t=midzero_list(disj_ident,disj_ident) rp=TCPar0
+ { let (mids,code) = t in
+ Ast0.wrap
+ (Ast0.DisjId(P.clt2mcode "(" lp,code,mids, P.clt2mcode ")" rp)) }
+
+type_ident: disj_ident { $1 }
+ | TTypeId
+ { Ast0.wrap(Ast0.Id(P.id2mcode $1)) }
decl_ident:
TDeclarerId
{ Ast0.wrap(Ast0.Id(P.id2mcode $1)) }
| TMetaDeclarer
{ let (nm,constraints,pure,clt) = $1 in
- Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) }
+ Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,Ast.NoVal,pure)) }
iter_ident:
TIteratorId
{ Ast0.wrap(Ast0.Id(P.id2mcode $1)) }
| TMetaIterator
{ let (nm,constraints,pure,clt) = $1 in
- Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) }
+ Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,Ast.NoVal,pure)) }
typedef_ident:
pure_ident
{ Ast0.wrap(Ast0.TypeName(P.id2mcode $1)) }
+ | TMeta { tmeta_to_type $1 }
| TMetaType
{ let (nm,pure,clt) = $1 in
Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure)) }
/*****************************************************************************/
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 }
| 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 }
/* ---------------------------------------------------------------------- */
/* doesn't allow only ... */
minus_start:
- fundecl { [Ast0.wrap(Ast0.DECL($1))] }
+ fundecl { [Ast0.wrap(Ast0.OTHER($1))] }
| ctype { [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Ty($1))))] }
| top_init { [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.TopInit($1))))] }
| toplevel_seq_startne(toplevel_after_dots_init)
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 */
{ (Ast0.wrap(Ast0.OTHER($1)))::$2 }
| expr plus_after_exp
{ (Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp($1)))))::$2 }
-| fundecl plus_after_stm { Ast0.wrap(Ast0.DECL($1))::$2 }
+| fundecl plus_after_stm { Ast0.wrap(Ast0.OTHER($1))::$2 }
| decl_statement_expr plus_after_stm
{ (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1)@$2 }
| TNothing plus_after_exp {$2}
| expr plus_after_exp
{ (Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp($1)))))::$2 }
-| fundecl plus_after_stm { Ast0.wrap(Ast0.DECL($1))::$2 }
+| fundecl plus_after_stm { Ast0.wrap(Ast0.OTHER($1))::$2 }
| decl_statement_expr plus_after_stm
{ (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1)@$2 }
plus_after_stm:
/* empty */ {[]}
| stm_dots plus_after_dots { (Ast0.wrap(Ast0.OTHER($1)))::$2 }
-| fundecl plus_after_stm { Ast0.wrap(Ast0.DECL($1))::$2 }
+| fundecl plus_after_stm { Ast0.wrap(Ast0.OTHER($1))::$2 }
| decl_statement plus_after_stm
{ (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1)@$2 }
/* ---------------------------------------------------------------------- */
-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
| 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
+ Iteration.parsed_virtual_identifiers :=
+ Common.union_set [nm]
+ !Iteration.parsed_virtual_identifiers;
let name = ("virtual", nm) in
let mv = Ast.MetaIdDecl(Ast.NONE,name) in
- (name,mv) }
+ (name,mv) }