diff --git a/mlx/lexer.mll b/mlx/lexer.mll
index 5f50394..67267d6 100644
--- a/mlx/lexer.mll
+++ b/mlx/lexer.mll
@@ -355,6 +355,7 @@ let kwdopchar =
let ident = (lowercase | uppercase) identchar*
let extattrident = ident ('.' ident)*
+let raw_ident_escape = "\\#"
let decimal_literal =
['0'-'9'] ['0'-'9' '_']*
@@ -396,6 +397,8 @@ rule token = parse
| ".~"
{ error lexbuf
(Reserved_sequence (".~", Some "is reserved for use in MetaOCaml")) }
+ | "~" raw_ident_escape (lowercase identchar * as name) ':'
+ { LABEL name }
| "~" (lowercase identchar * as name) ':'
{ check_label_name lexbuf name;
LABEL name }
@@ -404,17 +407,23 @@ rule token = parse
LABEL name }
| "?"
{ QUESTION }
+ | "?" raw_ident_escape (lowercase identchar * as name) ':'
+ { OPTLABEL name }
| "?" (lowercase identchar * as name) ':'
{ check_label_name lexbuf name;
OPTLABEL name }
| "?" (lowercase_latin1 identchar_latin1 * as name) ':'
{ warn_latin1 lexbuf;
OPTLABEL name }
+ | raw_ident_escape (lowercase identchar * as name)
+ { LIDENT name }
| lowercase identchar * as name
{ try Hashtbl.find keyword_table name
with Not_found -> LIDENT name }
| lowercase_latin1 identchar_latin1 * as name
{ warn_latin1 lexbuf; LIDENT name }
+ | "<" raw_ident_escape (lowercase identchar * as name)
+ { JSX_LIDENT name }
| "<" (lowercase identchar * as name)
{ JSX_LIDENT name }
| "<" "/" (lowercase identchar * as name)
diff --git a/ocamlmerlin_mlx/ocaml/preprocess/lexer_raw.mll b/ocamlmerlin_mlx/ocaml/preprocess/lexer_raw.mll
index a13899d..cc05d15 100644
--- a/ocamlmerlin_mlx/ocaml/preprocess/lexer_raw.mll
+++ b/ocamlmerlin_mlx/ocaml/preprocess/lexer_raw.mll
@@ -369,6 +369,7 @@ let kwdopchar =
let ident = (lowercase | uppercase) identchar*
let extattrident = ident ('.' ident)*
+let raw_ident_escape = "\\#"
let decimal_literal =
['0'-'9'] ['0'-'9' '_']*
@@ -426,6 +427,8 @@ rule token state = parse
{ fail lexbuf
(Reserved_sequence (".~", Some "is reserved for use in MetaOCaml")) }
*)
+ | "~" raw_ident_escape (lowercase identchar * as name) ':'
+ { return (LABEL name) }
| "~" (lowercase identchar * as name) ':'
{ lABEL (check_label_name lexbuf name) }
| "~" (lowercase_latin1 identchar_latin1 * as name) ':'
@@ -433,10 +436,14 @@ rule token state = parse
return (LABEL name) }
| "?"
{ return QUESTION }
+ | "?" raw_ident_escape (lowercase identchar * as name) ':'
+ { return (OPTLABEL name) }
| "?" (lowercase identchar * as name) ':'
{ oPTLABEL (check_label_name lexbuf name) }
| "?" (lowercase_latin1 identchar_latin1 * as name) ':'
{ warn_latin1 lexbuf; return (OPTLABEL name) }
+ | raw_ident_escape (lowercase identchar * as name)
+ { return (LIDENT name) }
| lowercase identchar * as name
{ return (try Hashtbl.find state.keywords name
with Not_found ->
@@ -445,6 +452,8 @@ rule token state = parse
LIDENT name) }
| lowercase_latin1 identchar_latin1 * as name
{ warn_latin1 lexbuf; return (LIDENT name) }
+ | "<" raw_ident_escape (lowercase identchar * as name)
+ { return (JSX_LIDENT name) }
| "<" (lowercase identchar * as name)
{ return (JSX_LIDENT name) }
| "<" "/" (lowercase identchar * as name)
diff --git a/test/mlx.t b/test/mlx.t
index ca39f60..3c43982 100644
--- a/test/mlx.t
+++ b/test/mlx.t
@@ -140,3 +140,73 @@ We have a lexer hack to parse [' | mlx-pp -print-tokens
+ let
+ _
+ =
+ <\#lazy
+ />
+ $ echo 'let _ = ' | mlx-pp -print-tokens
+ let
+ _
+ =
+