Pārlūkot izejas kodu

give better error for invalid escapes (closes #5126)

Simon Krajewski 9 gadi atpakaļ
vecāks
revīzija
fde68ed4e2

+ 7 - 4
src/syntax/ast.ml

@@ -641,6 +641,8 @@ let s_token = function
 	| At -> "@"
 	| Dollar v -> "$" ^ v
 
+exception Invalid_escape_sequence of char * int
+
 let unescape s =
 	let b = Buffer.create 0 in
 	let rec loop esc i =
@@ -648,6 +650,7 @@ let unescape s =
 			()
 		else
 			let c = s.[i] in
+			let fail () = raise (Invalid_escape_sequence(c,i)) in
 			if esc then begin
 				let inext = ref (i + 1) in
 				(match c with
@@ -656,11 +659,11 @@ let unescape s =
 				| 't' -> Buffer.add_char b '\t'
 				| '"' | '\'' | '\\' -> Buffer.add_char b c
 				| '0'..'3' ->
-					let c = (try char_of_int (int_of_string ("0o" ^ String.sub s i 3)) with _ -> raise Exit) in
+					let c = (try char_of_int (int_of_string ("0o" ^ String.sub s i 3)) with _ -> fail()) in
 					Buffer.add_char b c;
 					inext := !inext + 2;
 				| 'x' ->
-					let c = (try char_of_int (int_of_string ("0x" ^ String.sub s (i+1) 2)) with _ -> raise Exit) in
+					let c = (try char_of_int (int_of_string ("0x" ^ String.sub s (i+1) 2)) with _ -> fail()) in
 					Buffer.add_char b c;
 					inext := !inext + 2;
 				| 'u' ->
@@ -674,14 +677,14 @@ let unescape s =
 							assert (u <= 0x10FFFF);
 							(u, l+2)
 						with _ ->
-							raise Exit
+							fail()
 					in
 					let ub = UTF8.Buf.create 0 in
 					UTF8.Buf.add_char ub (UChar.uchar_of_int u);
 					Buffer.add_string b (UTF8.Buf.contents ub);
 					inext := !inext + a;
 				| _ ->
-					raise Exit);
+					fail());
 				loop false !inext;
 			end else
 				match c with

+ 4 - 4
src/syntax/lexer.mll

@@ -27,7 +27,7 @@ type error_msg =
 	| Unterminated_regexp
 	| Unclosed_comment
 	| Unclosed_code
-	| Invalid_escape
+	| Invalid_escape of char
 	| Invalid_option
 
 exception Error of error_msg * pos
@@ -39,7 +39,7 @@ let error_msg = function
 	| Unterminated_regexp -> "Unterminated regular expression"
 	| Unclosed_comment -> "Unclosed comment"
 	| Unclosed_code -> "Unclosed code string"
-	| Invalid_escape -> "Invalid escape sequence"
+	| Invalid_escape c -> Printf.sprintf "Invalid escape sequence \\%s" (Char.escaped c)
 	| Invalid_option -> "Invalid regular expression option"
 
 type lexer_file = {
@@ -303,14 +303,14 @@ and token = parse
 			reset();
 			let pmin = lexeme_start lexbuf in
 			let pmax = (try string lexbuf with Exit -> error Unterminated_string pmin) in
-			let str = (try unescape (contents()) with Exit -> error Invalid_escape pmin) in
+			let str = (try unescape (contents()) with Invalid_escape_sequence(c,i) -> error (Invalid_escape c) (pmin + i)) in
 			mk_tok (Const (String str)) pmin pmax;
 		}
 	| "'" {
 			reset();
 			let pmin = lexeme_start lexbuf in
 			let pmax = (try string2 lexbuf with Exit -> error Unterminated_string pmin) in
-			let str = (try unescape (contents()) with Exit -> error Invalid_escape pmin) in
+			let str = (try unescape (contents()) with Invalid_escape_sequence(c,i) -> error (Invalid_escape c) (pmin + i)) in
 			let t = mk_tok (Const (String str)) pmin pmax in
 			fast_add_fmt_string (snd t);
 			t

+ 4 - 0
tests/misc/projects/Issue5126/Main.hx

@@ -0,0 +1,4 @@
+class Main {
+	static var command:String = "(?'command'[a-zA-Z]+($|\s+))";
+	static function main() { }
+}

+ 3 - 0
tests/misc/projects/Issue5126/compile-fail.hxml

@@ -0,0 +1,3 @@
+-main Main
+-neko neko.n
+--no-output

+ 1 - 0
tests/misc/projects/Issue5126/compile-fail.hxml.stderr

@@ -0,0 +1 @@
+Main.hx:2: character 53 : Invalid escape sequence \s