|
@@ -111,25 +111,40 @@ let is_valid_identifier s =
|
|
|
with Exit ->
|
|
|
false
|
|
|
|
|
|
+let split_suffix s is_int =
|
|
|
+ let len = String.length s in
|
|
|
+ let rec loop i pivot =
|
|
|
+ if i = len then begin
|
|
|
+ match pivot with
|
|
|
+ | None ->
|
|
|
+ (s,None)
|
|
|
+ | Some pivot ->
|
|
|
+ (* There might be a _ at the end of the literal because we allow _f64 and such *)
|
|
|
+ let literal_length = if String.unsafe_get s (pivot - 1) = '_' then pivot - 1 else pivot in
|
|
|
+ let literal = String.sub s 0 literal_length in
|
|
|
+ let suffix = String.sub s pivot (len - pivot) in
|
|
|
+ (literal, Some suffix)
|
|
|
+ end else begin
|
|
|
+ let c = String.unsafe_get s i in
|
|
|
+ match c with
|
|
|
+ | 'i' | 'u' ->
|
|
|
+ loop (i + 1) (Some i)
|
|
|
+ | 'f' when not is_int ->
|
|
|
+ loop (i + 1) (Some i)
|
|
|
+ | _ ->
|
|
|
+ loop (i + 1) pivot
|
|
|
+ end
|
|
|
+ in
|
|
|
+ loop 0 None
|
|
|
+
|
|
|
let split_int_suffix s =
|
|
|
- let is_signed = String.contains s 'i' in
|
|
|
- match String.index_opt s (if is_signed then 'i' else 'u') with
|
|
|
- | Some pivot ->
|
|
|
- let literal = String.sub s 0 pivot in
|
|
|
- let suffix = String.sub s pivot ((String.length s) - pivot) in
|
|
|
- Const (Int (literal, Some suffix))
|
|
|
- | None ->
|
|
|
- Const (Int (s, None))
|
|
|
+ let (literal,suffix) = split_suffix s true in
|
|
|
+ Const (Int (literal,suffix))
|
|
|
|
|
|
let split_float_suffix s =
|
|
|
- match String.index_opt s 'f' with
|
|
|
- | Some pivot ->
|
|
|
- let literal = String.sub s 0 pivot in
|
|
|
- let suffix = String.sub s pivot ((String.length s) - pivot) in
|
|
|
- Const (Float (literal, Some suffix))
|
|
|
- | None ->
|
|
|
- Const (Float (s, None))
|
|
|
-
|
|
|
+ let (literal,suffix) = split_suffix s false in
|
|
|
+ Const (Float (literal,suffix))
|
|
|
+
|
|
|
let init file =
|
|
|
let f = make_file file in
|
|
|
cur := f;
|
|
@@ -318,11 +333,17 @@ let string_is_whitespace s =
|
|
|
|
|
|
let idtype = [%sedlex.regexp? Star '_', 'A'..'Z', Star ('_' | 'a'..'z' | 'A'..'Z' | '0'..'9')]
|
|
|
|
|
|
-let integer = [%sedlex.regexp? ('1'..'9', Star ('0'..'9')) | '0']
|
|
|
+let digit = [%sedlex.regexp? '0'..'9']
|
|
|
+let sep_digit = [%sedlex.regexp? Opt '_', digit]
|
|
|
+let integer_digits = [%sedlex.regexp? (digit, Star sep_digit)]
|
|
|
+let hex_digit = [%sedlex.regexp? '0'..'9'|'a'..'f'|'A'..'F']
|
|
|
+let sep_hex_digit = [%sedlex.regexp? Opt '_', hex_digit]
|
|
|
+let hex_digits = [%sedlex.regexp? (hex_digit, Star sep_hex_digit)]
|
|
|
+let integer = [%sedlex.regexp? ('1'..'9', Star sep_digit) | '0']
|
|
|
|
|
|
-let integer_suffix = [%sedlex.regexp? ('i'|'u'), Plus integer]
|
|
|
+let integer_suffix = [%sedlex.regexp? Opt '_', ('i'|'u'), Plus integer]
|
|
|
|
|
|
-let float_suffix = [%sedlex.regexp? 'f', Plus integer]
|
|
|
+let float_suffix = [%sedlex.regexp? Opt '_', 'f', Plus integer]
|
|
|
|
|
|
(* https://www.w3.org/TR/xml/#sec-common-syn plus '$' for JSX *)
|
|
|
let xml_name_start_char = [%sedlex.regexp? '$' | ':' | 'A'..'Z' | '_' | 'a'..'z' | 0xC0 .. 0xD6 | 0xD8 .. 0xF6 | 0xF8 .. 0x2FF | 0x370 .. 0x37D | 0x37F .. 0x1FFF | 0x200C .. 0x200D | 0x2070 .. 0x218F | 0x2C00 .. 0x2FEF | 0x3001 .. 0xD7FF | 0xF900 .. 0xFDCF | 0xFDF0 .. 0xFFFD | 0x10000 .. 0xEFFFF]
|
|
@@ -342,16 +363,16 @@ let rec token lexbuf =
|
|
|
| Plus (Chars " \t") -> token lexbuf
|
|
|
| "\r\n" -> newline lexbuf; token lexbuf
|
|
|
| '\n' | '\r' -> newline lexbuf; token lexbuf
|
|
|
- | "0x", Plus ('0'..'9'|'a'..'f'|'A'..'F'), Opt integer_suffix ->
|
|
|
+ | "0x", Plus hex_digits, Opt integer_suffix ->
|
|
|
mk lexbuf (split_int_suffix (lexeme lexbuf))
|
|
|
| integer, Opt integer_suffix ->
|
|
|
mk lexbuf (split_int_suffix (lexeme lexbuf))
|
|
|
| integer, float_suffix ->
|
|
|
mk lexbuf (split_float_suffix (lexeme lexbuf))
|
|
|
- | integer, '.', Plus '0'..'9', Opt float_suffix -> mk lexbuf (split_float_suffix (lexeme lexbuf))
|
|
|
- | '.', Plus '0'..'9', Opt float_suffix -> mk lexbuf (split_float_suffix (lexeme lexbuf))
|
|
|
- | integer, ('e'|'E'), Opt ('+'|'-'), Plus '0'..'9', Opt float_suffix -> mk lexbuf (split_float_suffix (lexeme lexbuf))
|
|
|
- | integer, '.', Star '0'..'9', ('e'|'E'), Opt ('+'|'-'), Plus '0'..'9', Opt float_suffix -> mk lexbuf (split_float_suffix (lexeme lexbuf))
|
|
|
+ | integer, '.', Plus integer_digits, Opt float_suffix -> mk lexbuf (split_float_suffix (lexeme lexbuf))
|
|
|
+ | '.', Plus integer_digits, Opt float_suffix -> mk lexbuf (split_float_suffix (lexeme lexbuf))
|
|
|
+ | integer, ('e'|'E'), Opt ('+'|'-'), Plus integer_digits, Opt float_suffix -> mk lexbuf (split_float_suffix (lexeme lexbuf))
|
|
|
+ | integer, '.', Star digit, ('e'|'E'), Opt ('+'|'-'), Plus integer_digits, Opt float_suffix -> mk lexbuf (split_float_suffix (lexeme lexbuf))
|
|
|
| integer, "..." ->
|
|
|
let s = lexeme lexbuf in
|
|
|
mk lexbuf (IntInterval (String.sub s 0 (String.length s - 3)))
|