module Text.XML.HXT.DTDValidation.RE
( RE(..)
, re_unit
, re_zero
, re_sym
, re_rep
, re_plus
, re_opt
, re_seq
, re_alt
, re_dot
, checkRE
, matches
, nullable
, printRE
)
where
import Data.List (foldl')
data RE a =
RE_ZERO String
| RE_UNIT
| RE_SYM a
| RE_DOT
| RE_REP (RE a)
| RE_PLUS (RE a)
| RE_OPT (RE a)
| RE_SEQ (RE a) (RE a)
| RE_ALT (RE a) (RE a)
deriving (Int -> RE a -> ShowS
[RE a] -> ShowS
RE a -> String
(Int -> RE a -> ShowS)
-> (RE a -> String) -> ([RE a] -> ShowS) -> Show (RE a)
forall a. Show a => Int -> RE a -> ShowS
forall a. Show a => [RE a] -> ShowS
forall a. Show a => RE a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> RE a -> ShowS
showsPrec :: Int -> RE a -> ShowS
$cshow :: forall a. Show a => RE a -> String
show :: RE a -> String
$cshowList :: forall a. Show a => [RE a] -> ShowS
showList :: [RE a] -> ShowS
Show, RE a -> RE a -> Bool
(RE a -> RE a -> Bool) -> (RE a -> RE a -> Bool) -> Eq (RE a)
forall a. Eq a => RE a -> RE a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => RE a -> RE a -> Bool
== :: RE a -> RE a -> Bool
$c/= :: forall a. Eq a => RE a -> RE a -> Bool
/= :: RE a -> RE a -> Bool
Eq, Eq (RE a)
Eq (RE a) =>
(RE a -> RE a -> Ordering)
-> (RE a -> RE a -> Bool)
-> (RE a -> RE a -> Bool)
-> (RE a -> RE a -> Bool)
-> (RE a -> RE a -> Bool)
-> (RE a -> RE a -> RE a)
-> (RE a -> RE a -> RE a)
-> Ord (RE a)
RE a -> RE a -> Bool
RE a -> RE a -> Ordering
RE a -> RE a -> RE a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (RE a)
forall a. Ord a => RE a -> RE a -> Bool
forall a. Ord a => RE a -> RE a -> Ordering
forall a. Ord a => RE a -> RE a -> RE a
$ccompare :: forall a. Ord a => RE a -> RE a -> Ordering
compare :: RE a -> RE a -> Ordering
$c< :: forall a. Ord a => RE a -> RE a -> Bool
< :: RE a -> RE a -> Bool
$c<= :: forall a. Ord a => RE a -> RE a -> Bool
<= :: RE a -> RE a -> Bool
$c> :: forall a. Ord a => RE a -> RE a -> Bool
> :: RE a -> RE a -> Bool
$c>= :: forall a. Ord a => RE a -> RE a -> Bool
>= :: RE a -> RE a -> Bool
$cmax :: forall a. Ord a => RE a -> RE a -> RE a
max :: RE a -> RE a -> RE a
$cmin :: forall a. Ord a => RE a -> RE a -> RE a
min :: RE a -> RE a -> RE a
Ord)
re_zero :: String -> RE a
re_zero :: forall a. String -> RE a
re_zero String
m = String -> RE a
forall a. String -> RE a
RE_ZERO String
m
re_unit :: RE a
re_unit :: forall a. RE a
re_unit = RE a
forall a. RE a
RE_UNIT
re_sym :: a -> RE a
re_sym :: forall a. a -> RE a
re_sym a
x = a -> RE a
forall a. a -> RE a
RE_SYM a
x
re_dot :: RE a
re_dot :: forall a. RE a
re_dot = RE a
forall a. RE a
RE_DOT
re_rep :: RE a -> RE a
re_rep :: forall a. RE a -> RE a
re_rep RE a
RE_UNIT = RE a
forall a. RE a
RE_UNIT
re_rep (RE_ZERO String
_) = RE a
forall a. RE a
RE_UNIT
re_rep e :: RE a
e@(RE_REP RE a
_) = RE a -> RE a
forall a. RE a -> RE a
RE_REP (RE a -> RE a
forall a. RE a -> RE a
rem_rep RE a
e)
re_rep e :: RE a
e@(RE_ALT RE a
_ RE a
_) = RE a -> RE a
forall a. RE a -> RE a
RE_REP (RE a -> RE a
forall a. RE a -> RE a
rem_rep RE a
e)
re_rep RE a
e = RE a -> RE a
forall a. RE a -> RE a
RE_REP RE a
e
rem_rep :: RE a -> RE a
rem_rep :: forall a. RE a -> RE a
rem_rep (RE_ALT RE a
RE_UNIT RE a
e2) = RE a
e2
rem_rep (RE_ALT RE a
e1 RE a
e2) = RE a -> RE a -> RE a
forall a. RE a -> RE a -> RE a
RE_ALT (RE a -> RE a
forall a. RE a -> RE a
rem_rep RE a
e1) (RE a -> RE a
forall a. RE a -> RE a
rem_rep RE a
e2)
rem_rep (RE_REP RE a
e1) = RE a -> RE a
forall a. RE a -> RE a
rem_rep RE a
e1
rem_rep RE a
e1 = RE a
e1
re_plus :: RE a -> RE a
re_plus :: forall a. RE a -> RE a
re_plus RE a
RE_UNIT = RE a
forall a. RE a
RE_UNIT
re_plus (RE_ZERO String
m) = String -> RE a
forall a. String -> RE a
RE_ZERO String
m
re_plus RE a
e
| RE a -> Bool
forall a. RE a -> Bool
nullable RE a
e = RE a -> RE a
forall a. RE a -> RE a
re_rep RE a
e
| Bool
otherwise = RE a -> RE a -> RE a
forall a. RE a -> RE a -> RE a
re_seq RE a
e (RE a -> RE a
forall a. RE a -> RE a
re_rep RE a
e)
re_opt :: (Ord a) => RE a -> RE a
re_opt :: forall a. Ord a => RE a -> RE a
re_opt RE a
RE_UNIT = RE a
forall a. RE a
RE_UNIT
re_opt (RE_ZERO String
_) = RE a
forall a. RE a
RE_UNIT
re_opt RE a
e = RE a -> RE a -> RE a
forall a. Ord a => RE a -> RE a -> RE a
re_alt RE a
forall a. RE a
RE_UNIT RE a
e
re_seq :: RE a -> RE a -> RE a
re_seq :: forall a. RE a -> RE a -> RE a
re_seq e1 :: RE a
e1@(RE_ZERO String
_) RE a
_ = RE a
e1
re_seq RE a
RE_UNIT RE a
e2 = RE a
e2
re_seq RE a
_ e2 :: RE a
e2@(RE_ZERO String
_) = RE a
e2
re_seq RE a
e1 RE a
RE_UNIT = RE a
e1
re_seq (RE_SEQ RE a
e11 RE a
e12) RE a
e2 = RE a -> RE a -> RE a
forall a. RE a -> RE a -> RE a
re_seq RE a
e11 (RE a -> RE a -> RE a
forall a. RE a -> RE a -> RE a
re_seq RE a
e12 RE a
e2)
re_seq RE a
e1 RE a
e2 = RE a -> RE a -> RE a
forall a. RE a -> RE a -> RE a
RE_SEQ RE a
e1 RE a
e2
re_alt :: (Ord a) => RE a -> RE a -> RE a
re_alt :: forall a. Ord a => RE a -> RE a -> RE a
re_alt (RE_ZERO String
_) RE a
e2 = RE a
e2
re_alt RE a
e1 (RE_ZERO String
_) = RE a
e1
re_alt (RE_ALT RE a
e11 RE a
e12) RE a
e2 = RE a -> RE a -> RE a
forall a. Ord a => RE a -> RE a -> RE a
re_alt RE a
e11 (RE a -> RE a -> RE a
forall a. Ord a => RE a -> RE a -> RE a
re_alt RE a
e12 RE a
e2)
re_alt RE a
e1 e2 :: RE a
e2@(RE_ALT RE a
e21 RE a
e22)
| RE a
e1 RE a -> RE a -> Bool
forall a. Eq a => a -> a -> Bool
== RE a
e21 = RE a
e2
| RE a
e1 RE a -> RE a -> Bool
forall a. Ord a => a -> a -> Bool
> RE a
e21 = RE a -> RE a -> RE a
forall a. Ord a => RE a -> RE a -> RE a
re_alt RE a
e21 (RE a -> RE a -> RE a
forall a. Ord a => RE a -> RE a -> RE a
re_alt RE a
e1 RE a
e22)
| Bool
otherwise = RE a -> RE a -> RE a
forall a. RE a -> RE a -> RE a
RE_ALT RE a
e1 RE a
e2
re_alt RE a
e1 RE a
e2
| RE a
e1 RE a -> RE a -> Bool
forall a. Eq a => a -> a -> Bool
== RE a
e2 = RE a
e2
| RE a
e1 RE a -> RE a -> Bool
forall a. Ord a => a -> a -> Bool
> RE a
e2 = RE a -> RE a -> RE a
forall a. Ord a => RE a -> RE a -> RE a
re_alt RE a
e2 RE a
e1
| Bool
otherwise = RE a -> RE a -> RE a
forall a. RE a -> RE a -> RE a
RE_ALT RE a
e1 RE a
e2
nullable :: RE a -> Bool
nullable :: forall a. RE a -> Bool
nullable (RE_ZERO String
_) = Bool
False
nullable RE a
RE_UNIT = Bool
True
nullable (RE_SYM a
_) = Bool
False
nullable (RE_REP RE a
_) = Bool
True
nullable (RE_PLUS RE a
e) = RE a -> Bool
forall a. RE a -> Bool
nullable RE a
e
nullable (RE_OPT RE a
_) = Bool
True
nullable (RE_SEQ RE a
e RE a
f) = RE a -> Bool
forall a. RE a -> Bool
nullable RE a
e Bool -> Bool -> Bool
&& RE a -> Bool
forall a. RE a -> Bool
nullable RE a
f
nullable (RE_ALT RE a
e RE a
f) = RE a -> Bool
forall a. RE a -> Bool
nullable RE a
e Bool -> Bool -> Bool
|| RE a -> Bool
forall a. RE a -> Bool
nullable RE a
f
nullable RE a
RE_DOT = Bool
False
delta :: (Ord a, Show a) => RE a -> a -> RE a
delta :: forall a. (Ord a, Show a) => RE a -> a -> RE a
delta RE a
re a
x = case RE a
re of
RE_ZERO String
_ -> RE a
re
RE a
RE_UNIT -> String -> RE a
forall a. String -> RE a
re_zero (String
"Symbol " String -> ShowS
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
x String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" unexpected.")
RE_SYM a
sym
| a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
sym -> RE a
forall a. RE a
re_unit
| Bool
otherwise -> String -> RE a
forall a. String -> RE a
re_zero (String
"Symbol " String -> ShowS
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
sym String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" expected, but symbol " String -> ShowS
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
x String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" found.")
RE_REP RE a
e -> RE a -> RE a -> RE a
forall a. RE a -> RE a -> RE a
re_seq (RE a -> a -> RE a
forall a. (Ord a, Show a) => RE a -> a -> RE a
delta RE a
e a
x) RE a
re
RE_PLUS RE a
e -> RE a -> RE a -> RE a
forall a. RE a -> RE a -> RE a
re_seq (RE a -> a -> RE a
forall a. (Ord a, Show a) => RE a -> a -> RE a
delta RE a
e a
x) (RE a -> RE a
forall a. RE a -> RE a
re_rep RE a
e)
RE_OPT RE a
e -> RE a -> a -> RE a
forall a. (Ord a, Show a) => RE a -> a -> RE a
delta RE a
e a
x
RE_SEQ RE a
e RE a
f
| RE a -> Bool
forall a. RE a -> Bool
nullable RE a
e -> RE a -> RE a -> RE a
forall a. Ord a => RE a -> RE a -> RE a
re_alt (RE a -> RE a -> RE a
forall a. RE a -> RE a -> RE a
re_seq (RE a -> a -> RE a
forall a. (Ord a, Show a) => RE a -> a -> RE a
delta RE a
e a
x) RE a
f) (RE a -> a -> RE a
forall a. (Ord a, Show a) => RE a -> a -> RE a
delta RE a
f a
x)
| Bool
otherwise -> RE a -> RE a -> RE a
forall a. RE a -> RE a -> RE a
re_seq (RE a -> a -> RE a
forall a. (Ord a, Show a) => RE a -> a -> RE a
delta RE a
e a
x) RE a
f
RE_ALT RE a
e RE a
f -> RE a -> RE a -> RE a
forall a. Ord a => RE a -> RE a -> RE a
re_alt (RE a -> a -> RE a
forall a. (Ord a, Show a) => RE a -> a -> RE a
delta RE a
e a
x) (RE a -> a -> RE a
forall a. (Ord a, Show a) => RE a -> a -> RE a
delta RE a
f a
x)
RE a
RE_DOT -> RE a
forall a. RE a
re_unit
matches :: (Ord a, Show a) => RE a -> [a] -> RE a
matches :: forall a. (Ord a, Show a) => RE a -> [a] -> RE a
matches RE a
e = (RE a -> a -> RE a) -> RE a -> [a] -> RE a
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' RE a -> a -> RE a
forall a. (Ord a, Show a) => RE a -> a -> RE a
delta RE a
e
checkRE :: (Eq a, Show a) => RE a -> String
checkRE :: forall a. (Eq a, Show a) => RE a -> String
checkRE (RE a
RE_UNIT) = String
""
checkRE (RE_ZERO String
m) = String
m
checkRE RE a
re
| RE a -> Bool
forall a. RE a -> Bool
nullable RE a
re = String
""
| Bool
otherwise = String
"Input must match " String -> ShowS
forall a. [a] -> [a] -> [a]
++ RE a -> String
forall a. (Eq a, Show a) => RE a -> String
printRE RE a
re
printRE :: (Eq a, Show a) => RE a -> String
printRE :: forall a. (Eq a, Show a) => RE a -> String
printRE RE a
re'
= String
"( " String -> ShowS
forall a. [a] -> [a] -> [a]
++ RE a -> String
forall {a}. (Show a, Eq a) => RE a -> String
printRE1 RE a
re' String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" )"
where
printRE1 :: RE a -> String
printRE1 RE a
re = case RE a
re of
RE_ZERO String
m -> String
"ERROR: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
m
RE a
RE_UNIT -> String
""
RE_SYM a
sym -> a -> String
forall a. Show a => a -> String
show a
sym
RE a
RE_DOT -> String
"."
RE_REP RE a
e
| RE a -> Bool
forall a. RE a -> Bool
isSingle RE a
e -> RE a -> String
printRE1 RE a
e String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"*"
| Bool
otherwise -> String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ RE a -> String
printRE1 RE a
e String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")*"
RE_PLUS RE a
e
| RE a -> Bool
forall a. RE a -> Bool
isSingle RE a
e -> RE a -> String
printRE1 RE a
e String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"+"
| Bool
otherwise -> String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ RE a -> String
printRE1 RE a
e String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")+"
RE_OPT RE a
e
| RE a -> Bool
forall a. RE a -> Bool
isSingle RE a
e -> RE a -> String
printRE1 RE a
e String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"?"
| Bool
otherwise -> String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ RE a -> String
printRE1 RE a
e String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")?"
RE_SEQ RE a
e1 (RE_REP RE a
e2)
| RE a
e1 RE a -> RE a -> Bool
forall a. Eq a => a -> a -> Bool
== RE a
e2 -> RE a -> String
printRE1 (RE a -> RE a
forall a. RE a -> RE a
RE_PLUS RE a
e1)
RE_SEQ RE a
e1 (RE_SEQ (RE_REP RE a
e2) RE a
e3)
| RE a
e1 RE a -> RE a -> Bool
forall a. Eq a => a -> a -> Bool
== RE a
e2 -> RE a -> String
printRE1 (RE a -> RE a -> RE a
forall a. RE a -> RE a -> RE a
RE_SEQ (RE a -> RE a
forall a. RE a -> RE a
RE_PLUS RE a
e1) RE a
e3)
RE_SEQ RE a
e RE a
f
| RE a -> Bool
forall a. RE a -> Bool
isAlt RE a
e Bool -> Bool -> Bool
&& Bool -> Bool
not (RE a -> Bool
forall a. RE a -> Bool
isAlt RE a
f) -> String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ RE a -> String
printRE1 RE a
e String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
") , " String -> ShowS
forall a. [a] -> [a] -> [a]
++ RE a -> String
printRE1 RE a
f
| Bool -> Bool
not (RE a -> Bool
forall a. RE a -> Bool
isAlt RE a
e) Bool -> Bool -> Bool
&& RE a -> Bool
forall a. RE a -> Bool
isAlt RE a
f -> RE a -> String
printRE1 RE a
e String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" , (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ RE a -> String
printRE1 RE a
f String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
| RE a -> Bool
forall a. RE a -> Bool
isAlt RE a
e Bool -> Bool -> Bool
&& RE a -> Bool
forall a. RE a -> Bool
isAlt RE a
f -> String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ RE a -> String
printRE1 RE a
e String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
") , (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ RE a -> String
printRE1 RE a
f String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
| Bool
otherwise -> RE a -> String
printRE1 RE a
e String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" , " String -> ShowS
forall a. [a] -> [a] -> [a]
++ RE a -> String
printRE1 RE a
f
RE_ALT RE a
RE_UNIT RE a
f -> RE a -> String
printRE1 (RE a -> RE a
forall a. RE a -> RE a
RE_OPT RE a
f)
RE_ALT RE a
e RE a
f
| RE a -> Bool
forall a. Eq a => RE a -> Bool
isSeq RE a
e Bool -> Bool -> Bool
&& Bool -> Bool
not (RE a -> Bool
forall a. Eq a => RE a -> Bool
isSeq RE a
f) -> String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ RE a -> String
printRE1 RE a
e String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
") | " String -> ShowS
forall a. [a] -> [a] -> [a]
++ RE a -> String
printRE1 RE a
f
| Bool -> Bool
not (RE a -> Bool
forall a. Eq a => RE a -> Bool
isSeq RE a
e) Bool -> Bool -> Bool
&& RE a -> Bool
forall a. Eq a => RE a -> Bool
isSeq RE a
f -> RE a -> String
printRE1 RE a
e String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" | (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ RE a -> String
printRE1 RE a
f String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
| RE a -> Bool
forall a. Eq a => RE a -> Bool
isSeq RE a
e Bool -> Bool -> Bool
&& RE a -> Bool
forall a. Eq a => RE a -> Bool
isSeq RE a
f -> String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ RE a -> String
printRE1 RE a
e String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
") | (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ RE a -> String
printRE1 RE a
f String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
| Bool
otherwise -> RE a -> String
printRE1 RE a
e String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" | " String -> ShowS
forall a. [a] -> [a] -> [a]
++ RE a -> String
printRE1 RE a
f
isSingle :: RE a -> Bool
isSingle :: forall a. RE a -> Bool
isSingle (RE_ZERO String
_) = Bool
True
isSingle RE a
RE_UNIT = Bool
True
isSingle (RE_SYM a
_) = Bool
True
isSingle RE a
_ = Bool
False
isSeq :: (Eq a) => RE a -> Bool
isSeq :: forall a. Eq a => RE a -> Bool
isSeq (RE_SEQ RE a
e1 (RE_REP RE a
e2))
| RE a
e1 RE a -> RE a -> Bool
forall a. Eq a => a -> a -> Bool
== RE a
e2 = Bool
False
isSeq (RE_SEQ RE a
_ RE a
_) = Bool
True
isSeq RE a
_ = Bool
False
isAlt :: RE a -> Bool
isAlt :: forall a. RE a -> Bool
isAlt (RE_ALT RE a
RE_UNIT RE a
_)= Bool
False
isAlt (RE_ALT RE a
_ RE a
_) = Bool
True
isAlt RE a
_ = Bool
False