(* Yoann Padioleau
- *
+ *
+ * Copyright (C) 2010, University of Copenhagen DIKU and INRIA.
* Copyright (C) 2006, 2007, 2008 Ecole des Mines de Nantes
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License (GPL)
* version 2 as published by the Free Software Foundation.
- *
+ *
* This program 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
open Common
-module TH = Token_helpers
+module TH = Token_helpers
(*****************************************************************************)
(* Wrappers *)
(*****************************************************************************)
-let pr2_err, pr2_once = Common.mk_pr2_wrappers Flag_parsing_c.verbose_parsing
+let pr2_err, pr2_once = Common.mk_pr2_wrappers Flag_parsing_c.verbose_parsing
(*****************************************************************************)
(* Helpers *)
(*****************************************************************************)
-let is_defined_passed_bis last_round =
+let is_defined_passed_bis last_round =
let xs = last_round +> List.filter TH.is_not_comment in
match xs with
| Parser_c.TDefine _::_ -> true
* looking for next synchro point starting from next may not be the
* best. So maybe we can find synchro point inside already_passed
* instead of looking in next.
- *
+ *
* But take care! must progress. We must not stay in infinite loop!
- * For instance now I have as a error recovery to look for
+ * For instance now I have as a error recovery to look for
* a "start of something", corresponding to start of function,
* but must go beyond this start otherwise will loop.
* So look at premier(external_declaration2) in parser.output and
* pass at least those first tokens.
- *
+ *
* I have chosen to start search for next synchro point after the
* first { I found, so quite sure we will not loop. *)
let last_round = List.rev already_passed in
- if is_defined_passed_bis last_round
+ if is_defined_passed_bis last_round
then find_next_synchro_define (last_round ++ next) []
- else
+ else
- let (before, after) =
- last_round +> Common.span (fun tok ->
+ let (before, after) =
+ last_round +> Common.span (fun tok ->
match tok with
(* by looking at TOBrace we are sure that the "start of something"
- * will not arrive too early
+ * will not arrive too early
*)
| Parser_c.TOBrace _ -> false
| Parser_c.TDefine _ -> false
| _ -> true
- )
+ )
in
find_next_synchro_orig (after ++ next) (List.rev before)
-
+
and find_next_synchro_define next already_passed =
match next with
- | [] ->
- pr2_err "ERROR-RECOV: end of file while in recovery mode";
+ | [] ->
+ pr2_err "ERROR-RECOV: end of file while in recovery mode";
already_passed, []
- | (Parser_c.TDefEOL i as v)::xs ->
+ | (Parser_c.TDefEOL i as v)::xs ->
pr2_err ("ERROR-RECOV: found sync end of #define, line "^i_to_s(TH.line_of_tok v));
v::already_passed, xs
- | v::xs ->
+ | v::xs ->
find_next_synchro_define xs (v::already_passed)
-
+
and find_next_synchro_orig next already_passed =
match next with
- | [] ->
- pr2_err "ERROR-RECOV: end of file while in recovery mode";
+ | [] ->
+ pr2_err "ERROR-RECOV: end of file while in recovery mode";
already_passed, []
- | (Parser_c.TCBrace i as v)::xs when TH.col_of_tok v =|= 0 ->
+ | (Parser_c.TCBrace i as v)::xs when TH.col_of_tok v =|= 0 ->
pr2_err ("ERROR-RECOV: found sync '}' at line "^i_to_s (TH.line_of_tok v));
(match xs with
| [] -> raise Impossible (* there is a EOF token normally *)
(* still useful: now parser.mly allow empty ';' so normally no pb *)
- | Parser_c.TPtVirg iptvirg::xs ->
+ | Parser_c.TPtVirg iptvirg::xs ->
pr2_err "ERROR-RECOV: found sync bis, eating } and ;";
(Parser_c.TPtVirg iptvirg)::v::already_passed, xs
- | Parser_c.TIdent x::Parser_c.TPtVirg iptvirg::xs ->
+ | Parser_c.TIdent x::Parser_c.TPtVirg iptvirg::xs ->
pr2_err "ERROR-RECOV: found sync bis, eating ident, }, and ;";
- (Parser_c.TPtVirg iptvirg)::(Parser_c.TIdent x)::v::already_passed,
+ (Parser_c.TPtVirg iptvirg)::(Parser_c.TIdent x)::v::already_passed,
xs
-
+
| Parser_c.TCommentSpace sp::Parser_c.TIdent x::Parser_c.TPtVirg iptvirg
- ::xs ->
+ ::xs ->
pr2_err "ERROR-RECOV: found sync bis, eating ident, }, and ;";
(Parser_c.TCommentSpace sp)::
(Parser_c.TPtVirg iptvirg)::
(Parser_c.TIdent x)::
v::
- already_passed,
+ already_passed,
xs
-
+
| Parser_c.TCommentNewline sp::Parser_c.TIdent x::Parser_c.TPtVirg iptvirg
- ::xs ->
+ ::xs ->
pr2_err "ERROR-RECOV: found sync bis, eating ident, }, and ;";
(Parser_c.TCommentNewline sp)::
(Parser_c.TPtVirg iptvirg)::
(Parser_c.TIdent x)::
v::
- already_passed,
+ already_passed,
xs
-
- | _ ->
+
+ | _ ->
v::already_passed, xs
)
- | v::xs when TH.col_of_tok v =|= 0 && TH.is_start_of_something v ->
+ | v::xs when TH.col_of_tok v =|= 0 && TH.is_start_of_something v ->
pr2_err ("ERROR-RECOV: found sync col 0 at line "^ i_to_s(TH.line_of_tok v));
already_passed, v::xs
-
- | v::xs ->
+
+ | v::xs ->
find_next_synchro_orig xs (v::already_passed)