X-Git-Url: https://git.hcoop.net/bpt/coccinelle.git/blobdiff_plain/fc1ad9719a3a6317b3a4749dac68e7272a3617db..feec80c30d140c69f5d894bd09b6071247d0fbaa:/parsing_cocci/context_neg.ml
diff --git a/parsing_cocci/context_neg.ml b/parsing_cocci/context_neg.ml
index 93997b5..5f9b8e7 100644
--- a/parsing_cocci/context_neg.ml
+++ b/parsing_cocci/context_neg.ml
@@ -1,25 +1,30 @@
(*
-* Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* 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 .
-*
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
+ * Copyright 2012, INRIA
+ * Julia Lawall, Gilles Muller
+ * Copyright 2010-2011, 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 .
+ *
+ * The authors reserve the right to distribute this or future versions of
+ * Coccinelle under other licenses.
+ *)
+
+
+# 0 "./context_neg.ml"
(* Detects subtrees that are all minus/plus and nodes that are "binding
context nodes". The latter is a node whose structure and immediate tokens
are the same in the minus and plus trees, and such that for every child,
@@ -57,7 +62,8 @@ let set_mcodekind x mcodekind =
| Ast0.IsoWhenTag(_) -> failwith "only within iso phase"
| Ast0.IsoWhenTTag(_) -> failwith "only within iso phase"
| Ast0.IsoWhenFTag(_) -> failwith "only within iso phase"
- | Ast0.MetaPosTag(p) -> failwith "metapostag only within iso phase"
+ | Ast0.MetaPosTag(p) -> failwith "invisible at this stage"
+ | Ast0.HiddenVarTag(p) -> failwith "hiddenvar only within iso phase"
let set_index x index =
match x with
@@ -81,7 +87,8 @@ let set_index x index =
| Ast0.IsoWhenTag(_) -> failwith "only within iso phase"
| Ast0.IsoWhenTTag(_) -> failwith "only within iso phase"
| Ast0.IsoWhenFTag(_) -> failwith "only within iso phase"
- | Ast0.MetaPosTag(p) -> failwith "metapostag only within iso phase"
+ | Ast0.MetaPosTag(p) -> failwith "invisible at this stage"
+ | Ast0.HiddenVarTag(p) -> failwith "hiddenvar only within iso phase"
let get_index = function
Ast0.DotsExprTag(d) -> Index.expression_dots d
@@ -104,7 +111,8 @@ let get_index = function
| Ast0.IsoWhenTag(_) -> failwith "only within iso phase"
| Ast0.IsoWhenTTag(_) -> failwith "only within iso phase"
| Ast0.IsoWhenFTag(_) -> failwith "only within iso phase"
- | Ast0.MetaPosTag(p) -> failwith "metapostag only within iso phase"
+ | Ast0.MetaPosTag(p) -> failwith "invisible at this stage"
+ | Ast0.HiddenVarTag(p) -> failwith "hiddenvar only within iso phase"
(* --------------------------------------------------------------------- *)
(* Collect the line numbers of the plus code. This is used for disjunctions.
@@ -141,7 +149,7 @@ let collect_plus_lines top =
let donothing r k e = k e in
let mcode (_,_,info,mcodekind,_,_) =
match mcodekind with
- Ast0.PLUS -> insert info.Ast0.pos_info.Ast0.line_start
+ Ast0.PLUS _ -> insert info.Ast0.pos_info.Ast0.line_start
| _ -> () in
let fn =
V0.flat_combiner bind option_default
@@ -153,7 +161,8 @@ let collect_plus_lines top =
(* --------------------------------------------------------------------- *)
-type kind = Neutral | AllMarked | NotAllMarked (* marked means + or - *)
+type kind =
+ Neutral | AllMarked of Ast.count | NotAllMarked (* marked means + or - *)
(* --------------------------------------------------------------------- *)
(* The first part analyzes each of the minus tree and the plus tree
@@ -176,7 +185,7 @@ type node =
let kind2c = function
Neutral -> "neutral"
- | AllMarked -> "allmarked"
+ | AllMarked _ -> "allmarked"
| NotAllMarked -> "notallmarked"
let node2c = function
@@ -189,8 +198,8 @@ tokens *)
let bind c1 c2 =
let lub = function
(k1,k2) when k1 = k2 -> k1
- | (Neutral,AllMarked) -> AllMarked
- | (AllMarked,Neutral) -> AllMarked
+ | (Neutral,AllMarked c) -> AllMarked c
+ | (AllMarked c,Neutral) -> AllMarked c
| _ -> NotAllMarked in
match (c1,c2) with
(* token/token *)
@@ -231,8 +240,8 @@ let option_default = (*Bind(Neutral,[],[],[],[],[])*)
let mcode (_,_,info,mcodekind,pos,_) =
let offset = info.Ast0.pos_info.Ast0.offset in
match mcodekind with
- Ast0.MINUS(_) -> Token(AllMarked,offset,mcodekind,[])
- | Ast0.PLUS -> Token(AllMarked,offset,mcodekind,[])
+ Ast0.MINUS(_) -> Token(AllMarked Ast.ONE,offset,mcodekind,[])
+ | Ast0.PLUS c -> Token(AllMarked c,offset,mcodekind,[])
| Ast0.CONTEXT(_) -> Token(NotAllMarked,offset,mcodekind,[offset])
| _ -> failwith "not possible"
@@ -240,7 +249,7 @@ let neutral_mcode (_,_,info,mcodekind,pos,_) =
let offset = info.Ast0.pos_info.Ast0.offset in
match mcodekind with
Ast0.MINUS(_) -> Token(Neutral,offset,mcodekind,[])
- | Ast0.PLUS -> Token(Neutral,offset,mcodekind,[])
+ | Ast0.PLUS _ -> Token(Neutral,offset,mcodekind,[])
| Ast0.CONTEXT(_) -> Token(Neutral,offset,mcodekind,[offset])
| _ -> failwith "not possible"
@@ -250,8 +259,8 @@ let nc_mcode (_,_,info,mcodekind,pos,_) =
(* distinguish from the offset of some real token *)
let offset = (-1) * info.Ast0.pos_info.Ast0.offset in
match mcodekind with
- Ast0.MINUS(_) -> Token(AllMarked,offset,mcodekind,[])
- | Ast0.PLUS -> Token(AllMarked,offset,mcodekind,[])
+ Ast0.MINUS(_) -> Token(AllMarked Ast.ONE,offset,mcodekind,[])
+ | Ast0.PLUS c -> Token(AllMarked c,offset,mcodekind,[])
| Ast0.CONTEXT(_) ->
(* Unlike the other mcode cases, we drop the offset from the context
offsets. This is because we don't know whether the term this is
@@ -269,9 +278,10 @@ let union_all l = List.fold_left Common.union_set [] l
intermingled with plus code. it is used in disj_cases *)
let classify is_minus all_marked table code =
let mkres builder k il tl bil btl l e =
- (if k = AllMarked
- then Ast0.set_mcodekind e (all_marked()) (* definitive *)
- else
+ (match k with
+ AllMarked count ->
+ Ast0.set_mcodekind e (all_marked count) (* definitive *)
+ | _ ->
let check_index il tl =
if List.for_all is_context tl
then
@@ -326,6 +336,13 @@ let classify is_minus all_marked table code =
(* no whencode in plus tree so have to drop it *)
(* need special cases for dots, nests, and disjs *)
+ let ident r k e =
+ compute_result Ast0.ident e
+ (match Ast0.unwrap e with
+ Ast0.DisjId(starter,id_list,_,ender) ->
+ disj_cases e starter id_list r.VT0.combiner_rec_ident ender
+ | _ -> k e) in
+
let expression r k e =
compute_result Ast0.expr e
(match Ast0.unwrap e with
@@ -343,6 +360,7 @@ let classify is_minus all_marked table code =
(* not clear why we have the next two cases, since DisjDecl and
DisjType shouldn't have been constructed yet, as they only come from isos *)
+ (* actually, DisjDecl now allowed in source struct decls *)
let declaration r k e =
compute_result Ast0.decl e
(match Ast0.unwrap e with
@@ -412,7 +430,8 @@ let classify is_minus all_marked table code =
| Ast0.Stars(dots,whencode) ->
k (Ast0.rewrap s (Ast0.Stars(dots,[])))
| Ast0.Disj(starter,statement_dots_list,_,ender) ->
- disj_cases s starter statement_dots_list r.VT0.combiner_rec_statement_dots
+ disj_cases s starter statement_dots_list
+ r.VT0.combiner_rec_statement_dots
ender
(* cases for everything with extra mcode *)
| Ast0.FunDecl((info,bef),_,_,_,_,_,_,_,_)
@@ -436,7 +455,7 @@ let classify is_minus all_marked table code =
(do_nothing Ast0.dotsExpr) (do_nothing Ast0.dotsInit)
(do_nothing Ast0.dotsParam) (do_nothing Ast0.dotsStmt)
(do_nothing Ast0.dotsDecl) (do_nothing Ast0.dotsCase)
- (do_nothing Ast0.ident) expression typeC initialiser param declaration
+ ident expression typeC initialiser param declaration
statement case_line (do_top Ast0.top) in
combiner.VT0.combiner_rec_top_level code
@@ -465,12 +484,17 @@ let dots fn d1 d2 =
let rec equal_ident i1 i2 =
match (Ast0.unwrap i1,Ast0.unwrap i2) with
(Ast0.Id(name1),Ast0.Id(name2)) -> equal_mcode name1 name2
- | (Ast0.MetaId(name1,_,_),Ast0.MetaId(name2,_,_)) ->
+ | (Ast0.MetaId(name1,_,_,_),Ast0.MetaId(name2,_,_,_)) ->
equal_mcode name1 name2
| (Ast0.MetaFunc(name1,_,_),Ast0.MetaFunc(name2,_,_)) ->
equal_mcode name1 name2
| (Ast0.MetaLocalFunc(name1,_,_),Ast0.MetaLocalFunc(name2,_,_)) ->
equal_mcode name1 name2
+ | (Ast0.DisjId(starter1,_,mids1,ender1),
+ Ast0.DisjId(starter2,_,mids2,ender2)) ->
+ equal_mcode starter1 starter2 &&
+ List.for_all2 equal_mcode mids1 mids2 &&
+ equal_mcode ender1 ender2
| (Ast0.OptIdent(_),Ast0.OptIdent(_)) -> true
| (Ast0.UniqueIdent(_),Ast0.UniqueIdent(_)) -> true
| _ -> false
@@ -483,6 +507,8 @@ let rec equal_expression e1 e2 =
equal_mcode lp1 lp2 && equal_mcode rp1 rp2
| (Ast0.Assignment(_,op1,_,_),Ast0.Assignment(_,op2,_,_)) ->
equal_mcode op1 op2
+ | (Ast0.Sequence(_,op1,_),Ast0.Sequence(_,op2,_)) ->
+ equal_mcode op1 op2
| (Ast0.CondExpr(_,why1,_,colon1,_),Ast0.CondExpr(_,why2,_,colon2,_)) ->
equal_mcode why1 why2 && equal_mcode colon1 colon2
| (Ast0.Postfix(_,op1),Ast0.Postfix(_,op2)) -> equal_mcode op1 op2
@@ -504,6 +530,8 @@ let rec equal_expression e1 e2 =
| (Ast0.SizeOfType(szf1,lp1,_,rp1),Ast0.SizeOfType(szf2,lp2,_,rp2)) ->
equal_mcode szf1 szf2 && equal_mcode lp1 lp2 && equal_mcode rp1 rp2
| (Ast0.TypeExp(_),Ast0.TypeExp(_)) -> true
+ | (Ast0.Constructor(lp1,_,rp1,_),Ast0.Constructor(lp2,_,rp2,_)) ->
+ equal_mcode lp1 lp2 && equal_mcode rp1 rp2
| (Ast0.MetaErr(name1,_,_),Ast0.MetaErr(name2,_,_))
| (Ast0.MetaExpr(name1,_,_,_,_),Ast0.MetaExpr(name2,_,_,_,_))
| (Ast0.MetaExprList(name1,_,_),Ast0.MetaExprList(name2,_,_)) ->
@@ -537,6 +565,8 @@ let rec equal_typeC t1 t2 =
equal_mcode lb1 lb2 && equal_mcode rb1 rb2
| (Ast0.EnumName(kind1,_),Ast0.EnumName(kind2,_)) ->
equal_mcode kind1 kind2
+ | (Ast0.EnumDef(_,lb1,_,rb1),Ast0.EnumDef(_,lb2,_,rb2)) ->
+ equal_mcode lb1 lb2 && equal_mcode rb1 rb2
| (Ast0.StructUnionName(kind1,_),Ast0.StructUnionName(kind2,_)) ->
equal_mcode kind1 kind2
| (Ast0.FunctionType(ty1,lp1,p1,rp1),Ast0.FunctionType(ty2,lp2,p2,rp2)) ->
@@ -558,18 +588,29 @@ let rec equal_typeC t1 t2 =
let equal_declaration d1 d2 =
match (Ast0.unwrap d1,Ast0.unwrap d2) with
- (Ast0.Init(stg1,_,_,eq1,_,sem1),Ast0.Init(stg2,_,_,eq2,_,sem2)) ->
+ (Ast0.MetaDecl(name1,_),Ast0.MetaDecl(name2,_))
+ | (Ast0.MetaField(name1,_),Ast0.MetaField(name2,_))
+ | (Ast0.MetaFieldList(name1,_,_),Ast0.MetaFieldList(name2,_,_)) ->
+ equal_mcode name1 name2
+ | (Ast0.Init(stg1,_,_,eq1,_,sem1),Ast0.Init(stg2,_,_,eq2,_,sem2)) ->
equal_option stg1 stg2 && equal_mcode eq1 eq2 && equal_mcode sem1 sem2
| (Ast0.UnInit(stg1,_,_,sem1),Ast0.UnInit(stg2,_,_,sem2)) ->
equal_option stg1 stg2 && equal_mcode sem1 sem2
- | (Ast0.MacroDecl(nm1,lp1,_,rp1,sem1),Ast0.MacroDecl(nm2,lp2,_,rp2,sem2)) ->
+ | (Ast0.MacroDecl(nm1,lp1,_,rp1,sem1),Ast0.MacroDecl(nm2,lp2,_,rp2,sem2))->
equal_mcode lp1 lp2 && equal_mcode rp1 rp2 && equal_mcode sem1 sem2
+ | (Ast0.MacroDeclInit(nm1,lp1,_,rp1,eq1,_,sem1),
+ Ast0.MacroDeclInit(nm2,lp2,_,rp2,eq2,_,sem2))->
+ equal_mcode lp1 lp2 && equal_mcode rp1 rp2 && equal_mcode eq1 eq2
+ && equal_mcode sem1 sem2
| (Ast0.TyDecl(_,sem1),Ast0.TyDecl(_,sem2)) -> equal_mcode sem1 sem2
| (Ast0.Ddots(dots1,_),Ast0.Ddots(dots2,_)) -> equal_mcode dots1 dots2
| (Ast0.OptDecl(_),Ast0.OptDecl(_)) -> true
| (Ast0.UniqueDecl(_),Ast0.UniqueDecl(_)) -> true
- | (Ast0.DisjDecl _,_) | (_,Ast0.DisjDecl _) ->
- failwith "DisjDecl not expected here"
+ | (Ast0.DisjDecl(starter1,_,mids1,ender1),
+ Ast0.DisjDecl(starter2,_,mids2,ender2)) ->
+ equal_mcode starter1 starter2 &&
+ List.for_all2 equal_mcode mids1 mids2 &&
+ equal_mcode ender1 ender2
| _ -> false
let equal_designator d1 d2 =
@@ -588,8 +629,12 @@ let equal_initialiser i1 i2 =
match (Ast0.unwrap i1,Ast0.unwrap i2) with
(Ast0.MetaInit(name1,_),Ast0.MetaInit(name2,_)) ->
equal_mcode name1 name2
+ | (Ast0.MetaInitList(name1,_,_),Ast0.MetaInitList(name2,_,_)) ->
+ equal_mcode name1 name2
| (Ast0.InitExpr(_),Ast0.InitExpr(_)) -> true
- | (Ast0.InitList(lb1,_,rb1),Ast0.InitList(lb2,_,rb2)) ->
+ | (Ast0.InitList(lb1,_,rb1,o1),Ast0.InitList(lb2,_,rb2,o2)) ->
+ (* can't compare orderedness, because this can differ between -
+ and + code *)
(equal_mcode lb1 lb2) && (equal_mcode rb1 rb2)
| (Ast0.InitGccExt(designators1,eq1,_),
Ast0.InitGccExt(designators2,eq2,_)) ->
@@ -683,6 +728,8 @@ let rec equal_statement s1 s2 =
| (Ast0.Stars(d1,_),Ast0.Stars(d2,_)) -> equal_mcode d1 d2
| (Ast0.Include(inc1,name1),Ast0.Include(inc2,name2)) ->
equal_mcode inc1 inc2 && equal_mcode name1 name2
+ | (Ast0.Undef(def1,_),Ast0.Undef(def2,_)) ->
+ equal_mcode def1 def2
| (Ast0.Define(def1,_,_,_),Ast0.Define(def2,_,_,_)) ->
equal_mcode def1 def2
| (Ast0.OptStm(_),Ast0.OptStm(_)) -> true
@@ -713,7 +760,7 @@ let equal_case_line c1 c2 =
let rec equal_top_level t1 t2 =
match (Ast0.unwrap t1,Ast0.unwrap t2) with
- (Ast0.DECL(_),Ast0.DECL(_)) -> true
+ (Ast0.NONDECL(_),Ast0.NONDECL(_)) -> true
| (Ast0.FILEINFO(old_file1,new_file1),Ast0.FILEINFO(old_file2,new_file2)) ->
equal_mcode old_file1 old_file2 && equal_mcode new_file1 new_file2
| (Ast0.CODE(_),Ast0.CODE(_)) -> true
@@ -833,10 +880,11 @@ let plus_table =
let iscode t =
match Ast0.unwrap t with
- Ast0.DECL(_) -> true
+ Ast0.NONDECL(_) -> true
| Ast0.FILEINFO(_) -> true
| Ast0.ERRORWORDS(_) -> false
| Ast0.CODE(_) -> true
+ | Ast0.TOPCODE(_)
| Ast0.OTHER(_) -> failwith "unexpected top level code"
(* ------------------------------------------------------------------- *)
@@ -850,7 +898,7 @@ let concat = function
[] -> []
| x::rest ->
(match Ast0.unwrap x with
- Ast0.DECL(s) -> let stms = loop rest in s::stms
+ Ast0.NONDECL(s) -> let stms = loop rest in s::stms
| Ast0.CODE(ss) ->
let stms = loop rest in
(match Ast0.unwrap ss with
@@ -931,14 +979,17 @@ let rec is_toplevel s =
Ast0.Decl(_,e) -> true
| Ast0.FunDecl(_,_,_,_,_,_,_,_,_) -> true
| Ast0.Disj(_,stmts,_,_) -> isall is_toplevel stmts
- | Ast0.ExprStatement(fc,_) ->
+ | Ast0.ExprStatement(Some fc,_) ->
(match Ast0.unwrap fc with
Ast0.FunCall(_,_,_,_) -> true
| _ -> false)
| Ast0.Include(_,_) -> true
+ | Ast0.Undef(_,_) -> true
| Ast0.Define(_,_,_,_) -> true
| _ -> false
+(* consider code and topcode to be the same; difference handled
+in top_level.ml *)
let check_compatible m p =
let fail _ =
failwith
@@ -946,17 +997,21 @@ let check_compatible m p =
"incompatible minus and plus code starting on lines %d and %d"
(Ast0.get_line m) (Ast0.get_line p)) in
match (Ast0.unwrap m, Ast0.unwrap p) with
- (Ast0.DECL(decl1),Ast0.DECL(decl2)) ->
+ (Ast0.NONDECL(decl1),Ast0.NONDECL(decl2)) ->
if not (is_decl decl1 && is_decl decl2)
then fail()
- | (Ast0.DECL(decl1),Ast0.CODE(code2)) ->
+ | (Ast0.NONDECL(decl1),Ast0.CODE(code2)) ->
+ (* This is probably the only important case. We don't want to
+ replace top-level declarations by arbitrary code. *)
let v1 = is_decl decl1 in
let v2 = List.for_all is_toplevel (Ast0.undots code2) in
- if !Flag.make_hrule = None && v1 && not v2 then fail()
- | (Ast0.CODE(code1),Ast0.DECL(decl2)) ->
+ if !Flag.make_hrule = None && v1 && not v2
+ then fail()
+ | (Ast0.CODE(code1),Ast0.NONDECL(decl2)) ->
let v1 = List.for_all is_toplevel (Ast0.undots code1) in
let v2 = is_decl decl2 in
- if v1 && not v2 then fail()
+ if v1 && not v2
+ then fail()
| (Ast0.CODE(code1),Ast0.CODE(code2)) ->
let v1 = isonly is_init code1 in
let v2a = isonly is_init code2 in
@@ -974,11 +1029,29 @@ let check_compatible m p =
testers;
let v1 = isonly is_fndecl code1 in
let v2 = List.for_all is_toplevel (Ast0.undots code2) in
- if !Flag.make_hrule = None && v1 && not v2 then fail()
+ if !Flag.make_hrule = None && v1 && not v2
+ then fail()
| (Ast0.FILEINFO(_,_),Ast0.FILEINFO(_,_)) -> ()
| (Ast0.OTHER(_),Ast0.OTHER(_)) -> ()
| _ -> fail()
+(* can't just remove expressions or types, not sure if all cases are needed. *)
+let check_complete m =
+ match Ast0.unwrap m with
+ Ast0.NONDECL(code) ->
+ if is_exp code or is_ty code
+ then
+ failwith
+ (Printf.sprintf "invalid minus starting on line %d"
+ (Ast0.get_line m))
+ | Ast0.CODE(code) ->
+ if isonly is_exp code or isonly is_ty code
+ then
+ failwith
+ (Printf.sprintf "invalid minus starting on line %d"
+ (Ast0.get_line m))
+ | _ -> ()
+
(* ------------------------------------------------------------------- *)
(* returns a list of corresponding minus and plus trees *)
@@ -992,12 +1065,14 @@ let context_neg minus plus =
| ([],l) ->
failwith (Printf.sprintf "%d plus things remaining" (List.length l))
| (minus,[]) ->
+ List.iter check_complete minus;
plus_lines := [];
let _ =
List.map
(function m ->
classify true
- (function _ -> Ast0.MINUS(ref([],Ast0.default_token_info)))
+ (function _ ->
+ Ast0.MINUS(ref(Ast.NOREPLACEMENT,Ast0.default_token_info)))
minus_table m)
minus in
[]
@@ -1023,9 +1098,10 @@ let context_neg minus plus =
collect_plus_lines p;
let _ =
classify true
- (function _ -> Ast0.MINUS(ref([],Ast0.default_token_info)))
+ (function _ ->
+ Ast0.MINUS(ref(Ast.NOREPLACEMENT,Ast0.default_token_info)))
minus_table m in
- let _ = classify false (function _ -> Ast0.PLUS) plus_table p in
+ let _ = classify false (function c -> Ast0.PLUS c) plus_table p in
traverse minus_table plus_table;
(m,p)::loop(minus,plus)
end
@@ -1039,7 +1115,9 @@ let context_neg minus plus =
plus_lines := [];
let _ =
classify true
- (function _ -> Ast0.MINUS(ref([],Ast0.default_token_info)))
+ (function _ ->
+ Ast0.MINUS(ref(Ast.NOREPLACEMENT,
+ Ast0.default_token_info)))
minus_table m in
loop(minus,pall)
end