diff options
author | Chimrod <> | 2024-01-20 19:46:16 +0100 |
---|---|---|
committer | Chimrod <> | 2024-01-20 19:46:16 +0100 |
commit | 2abe1fae40a1c65ff66ad51c98d92be9c7d9d8a5 (patch) | |
tree | beb44b0afe74943af50d2b39a6317ff42f1ac0b7 /lib/qparser | |
parent | 86fd78a5ab65015a9c18ad601856f1b16ed90fa9 (diff) |
Better recovery after an error — prevent an infinite loop
Diffstat (limited to 'lib/qparser')
-rw-r--r-- | lib/qparser/lexbuf.mli | 3 | ||||
-rw-r--r-- | lib/qparser/lexer.ml | 55 |
2 files changed, 14 insertions, 44 deletions
diff --git a/lib/qparser/lexbuf.mli b/lib/qparser/lexbuf.mli index ac3b262..f9812a7 100644 --- a/lib/qparser/lexbuf.mli +++ b/lib/qparser/lexbuf.mli @@ -64,7 +64,8 @@ type state = | String of stringWraper (** String enclosed by [''] *) | MString of int (** String enclosed by [{}]*) | EndString of stringWraper - (** State raised just before closing the string *) + (** State raised just before closing the string. + The buffer is rollbacked and the position is the closing symbol. *) | Expression (** Expression where [!] is an operator *) val pp_state : Format.formatter -> state -> unit diff --git a/lib/qparser/lexer.ml b/lib/qparser/lexer.ml index 4e9aa27..5c093b1 100644 --- a/lib/qparser/lexer.ml +++ b/lib/qparser/lexer.ml @@ -119,6 +119,10 @@ let rec read_quoted_string : Lexbuf.stringWraper -> Lexbuf.buffer_builder = let lexbuf = Lexbuf.buffer buffer in match%sedlex lexbuf with | "<<" -> + (* Enter into embed code. We enter here into a new state until the + matching >>. + If we already got some text before, report the literal token, then + rollback to read the embeded code again. *) if not nested then ( match Buffer.length buf with | 0 -> @@ -276,50 +280,15 @@ let rec discard buffer = let lexbuf = Lexbuf.buffer buffer in match%sedlex lexbuf with - | '\'' -> ( - match Lexbuf.state buffer with - | Some (Lexbuf.String _) | Some (Lexbuf.EndString _) -> - (* If we are inside a string, or just beforce closing it, close it. - *) - Lexbuf.leave_state buffer; - discard buffer - | _ -> - (* Otherwise wait skip until the end of the starting one *) - Lexbuf.enter_state buffer (Lexbuf.String Lex_state.quotedStringWraper); - (try - ignore - (read_quoted_string Lex_state.quotedStringWraper - (Buffer.create 16) buffer) - with e -> - Printexc.print_backtrace stdout; - - raise e); - discard buffer) - | '"' -> ( - match Lexbuf.state buffer with - | Some (Lexbuf.String _) | Some (Lexbuf.EndString _) -> - Lexbuf.leave_state buffer; - discard buffer - | _ -> - Lexbuf.enter_state buffer - (Lexbuf.String Lex_state.dQuotedStringWraper); - ignore - (read_quoted_string Lex_state.dQuotedStringWraper (Buffer.create 16) - buffer); - discard buffer) - | '}' -> ( - match Lexbuf.state buffer with - | Some (Lexbuf.MString _) -> - Lexbuf.leave_state buffer; - discard buffer - | _ -> - ignore (read_long_string 0 (Buffer.create 16) buffer); - discard buffer) - | '{' -> - ignore (read_long_string 0 (Buffer.create 16) buffer); - Lexbuf.leave_state buffer; - discard buffer | '-', Plus '-', Star (Sub (any, ('\r' | '\n'))) -> + (* If something looks like the end of a location, get out the discard + mode. + We can’t really be sure if it is effectively the end of a + location (because we can be in a text), but trying to figure if it is + or not just don’t make sense. + + We are here because an error was raised, so can have any situation + (for example a missing quote). *) leave_expression buffer; () | '!' -> |