Commit 16c128d2 authored by Kim Nguyễn's avatar Kim Nguyễn
Browse files

Fix parsing of intervals in regular expressions.

parent 3f7498a2
......@@ -62,6 +62,7 @@ let pp_token ?(content = false) fmt t =
| MINUS -> pp "%s" "MINUS"
| MINUSGT -> pp "%s" "MINUSGT"
| MINUSMINUS -> pp "%s" "MINUSMINUS"
| MINUSMINUSSTAR -> pp "%s" "MINUSMINUSSTAR"
| MOD -> pp "%s" "MOD"
| NAMESPACE -> pp "%s" "NAMESPACE"
| OFF -> pp "%s" "OFF"
......@@ -91,6 +92,7 @@ let pp_token ?(content = false) fmt t =
| SLASHAT -> pp "%s" "SLASHAT"
| SLASHSLASH -> pp "%s" "SLASHSLASH"
| STAR -> pp "%s" "STAR"
| STARMINUSMINUS -> pp "%s" "STARMINUSMINUS"
| STARQMARK -> pp "%s" "STARQMARK"
| STARSTAR -> pp "%s" "STARSTAR"
| STRING1 s ->
......@@ -164,6 +166,7 @@ let all_tokens =
(MINUS, "-");
(MINUSGT, "->");
(MINUSMINUS, "--");
(MINUSMINUSSTAR, "--*");
(MOD, "mod");
(NAMESPACE, "namespace");
(OFF, "off");
......@@ -191,6 +194,7 @@ let all_tokens =
(SLASHAT, "/@");
(SLASHSLASH, "//");
(STAR, "*");
(STARMINUSMINUS, "*--");
(STARQMARK, "?");
(STARSTAR, "**");
(STRING1 "hello", "a character literal");
......
......@@ -68,6 +68,20 @@ let mk_rec_field loc lab def =
let x = if o then mk loc (Optional x) else x in
(label lab, (x, y))
let mk_interval loc it =
let open Intervals in
match it with
None, Some j ->
let j = V.mk j in
mk loc (Internal (Types.interval (left j)))
| Some i, None ->
let i = V.mk i in
mk loc (Internal (Types.interval (right i)))
| Some i, Some j ->
let i = V.mk i and j = V.mk j in
mk loc (Internal (Types.interval (bounded i j)))
| None, None -> parsing_error loc
(Format.sprintf "invalid interval *--*")
let rec is_not = function
Var id when U.to_string id = "not" -> true
......@@ -145,7 +159,9 @@ let mk_app_pat loc var l =
%token BANG "!"
%token COLCOL "::"
%token DOTDOT ".."
%token MINUSMINUS "--"
%token MINUSMINUS "--"
%token STARMINUSMINUS "*--"
%token MINUSMINUSSTAR "--*"
%token QMARKQMARK "??" PLUSQMARK "+?" STARQMARK "*?"
%token EQQMARK "=?"
%token UNDERSCORE "_"
......@@ -379,26 +395,10 @@ constr_pat:
let i = CharSet.V.mk_int i in
let j = CharSet.V.mk_int j in
mk $sloc (Internal (Types.char (CharSet.mk_classes [i, j]))) }
| i = int_or_star "--" j = int_or_star {
let open Intervals in
match i, j with
None, Some j ->
let j = V.mk j in
mk $sloc (Internal (Types.interval (left j)))
| Some i, None ->
let i = V.mk i in
mk $sloc (Internal (Types.interval (right i)))
| Some i, Some j ->
let i = V.mk i and j = V.mk j in
mk $sloc (Internal (Types.interval (bounded i j)))
| None, None -> parsing_error $sloc
(Format.sprintf "invalid interval *--*")
| it = interval {
mk_interval $sloc it
}
| i = int_pat {
let open Intervals in
let i = V.mk i in
mk $sloc (Internal (Types.interval (atom i)))
}
| i = int_pat { mk_interval $sloc (Some i, Some i) }
| s = simple_pat { s }
;
......@@ -509,9 +509,10 @@ ident_or_keyword:
| "-" i = INT { "-" ^ i }
;
int_or_star:
| i = int_pat { Some i }
| "*" { None }
%inline interval:
| i = int_pat "--" j = int_pat { Some i, Some j }
| "*--" j = int_pat { None, Some j}
| i = int_pat "--*" { Some i, None }
;
tag_type:
......@@ -651,11 +652,10 @@ regexp_simple:
l
Epsilon
}
| i = INT {
let open Intervals in
let i = V.mk i in
Elem (mk $sloc (Internal (Types.interval (atom i))))
}
| it = interval {
Elem (mk_interval $sloc it)
}
| i = int_pat { Elem (mk_interval $sloc (Some i, Some i)) }
| id = ident_or_keyword_no_ref_no_where {
match id with
"PCDATA" -> string_regexp
......
......@@ -394,9 +394,11 @@ let rec token lexbuf =
| "::" -> COLCOL
| ".." -> DOTDOT
| "--" -> MINUSMINUS
| "--*" -> MINUSMINUSSTAR
| "??" -> QMARKQMARK
| "+?" -> PLUSQMARK
| "*?" -> STARQMARK
| "*--" -> STARMINUSMINUS
| "=?" -> EQQMARK
| "||" -> BARBAR
| ";;" -> SEMISEMI
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment