diff options
Diffstat (limited to 'parsing/lexer.mll')
-rw-r--r-- | parsing/lexer.mll | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/parsing/lexer.mll b/parsing/lexer.mll index 2ac3036ea7..2670e8f0e5 100644 --- a/parsing/lexer.mll +++ b/parsing/lexer.mll @@ -27,6 +27,7 @@ type error = | Unterminated_string_in_comment | Keyword_as_label of string | Literal_overflow of string + | Unterminated_regexp ;; exception Error of error * Location.t;; @@ -203,6 +204,8 @@ let report_error ppf = function fprintf ppf "`%s' is a keyword, it cannot be used as label name" kwd | Literal_overflow ty -> fprintf ppf "Integer literal exceeds the range of representable integers of type %s" ty + | Unterminated_regexp -> + fprintf ppf "Regular expression not terminated" ;; } @@ -331,6 +334,15 @@ rule token = parse lexbuf.lex_curr_p <- { curpos with pos_cnum = curpos.pos_cnum - 1 }; STAR } + | "[/" + { reset_string_buffer (); + let string_start = lexbuf.lex_start_p in + (* let switches = regexp lexbuf in *) + let _ = regexp lexbuf in + lexbuf.lex_start_p <- string_start; + REGEXP (get_stored_string()) + } + | "#" [' ' '\t']* (['0'-'9']+ as num) [' ' '\t']* ("\"" ([^ '\010' '\013' '"' ] * as name) "\"")? [^ '\010' '\013'] * newline @@ -503,3 +515,18 @@ and skip_sharp_bang = parse | "#!" [^ '\n']* '\n' { update_loc lexbuf None 1 false 0 } | "" { () } + +and regexp = parse + | '/' ['i' 'm' 's']* ']' + (* x is not supported, due to the lexer complexity *) + { let lx = Lexing.lexeme lexbuf in + String.sub lx 1 (String.length lx - 2) + } + | ((_ # ['/' '\\']) | '\\' _) + + { String.iter store_string_char (Lexing.lexeme lexbuf); + regexp lexbuf + } + | '/' (* never matches with /] *) + { store_string_char '/'; + regexp lexbuf } + | "" { raise (Error (Unterminated_regexp, !string_start_loc)) } |