0 | module Text.ILex.RExp
3 | import Data.ByteString
5 | import Decidable.HDecEq
6 | import public Text.ILex.Char.Set
7 | import Derive.Prelude
10 | %language ElabReflection
21 | data RExpOf : Bool -> Type -> Type where
22 | Eps : RExpOf False t
23 | Ch : SetOf t -> RExpOf True t
24 | And : RExpOf b1 t -> RExpOf b2 t -> RExpOf (b1 || b2) t
25 | Or : RExpOf b1 t -> RExpOf b2 t -> RExpOf (b1 && b2) t
26 | Star : RExpOf True t -> RExpOf False t
28 | %runElab derivePattern "RExpOf" [I,P] [Show]
31 | 0 RExp : Bool -> Type
32 | RExp b = RExpOf b Bits32
35 | 0 RExp8 : Bool -> Type
36 | RExp8 b = RExpOf b Bits8
39 | data IsCh : RExpOf b t -> Type where
40 | ItIsCh : IsCh (Ch s)
43 | adjRanges : (SetOf t -> RExpOf True s) -> RExpOf b t -> RExpOf b s
44 | adjRanges f Eps = Eps
45 | adjRanges f (Ch x) = f x
46 | adjRanges f (And x y) = And (adjRanges f x) (adjRanges f y)
47 | adjRanges f (Or x y) = Or (adjRanges f x) (adjRanges f y)
48 | adjRanges f (Star x) = Star (adjRanges f x)
55 | 0 TokenMap : Type -> Type
56 | TokenMap a = List (RExp True, a)
59 | 0 TokenMap8 : Type -> Type
60 | TokenMap8 a = List (RExp8 True, a)
67 | orF : RExpOf (b || False) t -> RExpOf b t
68 | orF x = replace {p = \b => RExpOf b t} (orFalseNeutral b) x
71 | orT : RExpOf (b || True) t -> RExpOf True t
72 | orT x = replace {p = \b => RExpOf b t} (orTrueTrue b) x
75 | toOrF : RExpOf b t -> RExpOf (b || False) t
76 | toOrF x = replace {p = \b => RExpOf b t} (sym $
orFalseNeutral b) x
83 | public export %inline
84 | chr : Char -> RExp True
87 | public export %inline
88 | fromChar : Char -> RExp True
93 | charLike : Char -> RExp True
96 | True => Or (chr c) (chr $
toUpper c)
97 | False => case isUpper c of
98 | True => Or (chr c) (chr $
toLower c)
101 | parameters {auto bnd : WithBounds t}
104 | public export %inline
105 | not : (r : RExpOf b t) -> (0 p : IsCh r) => RExpOf True t
106 | not (Ch s) = Ch $
negation s
108 | public export %inline
109 | (&&) : (x,y : RExpOf b t) -> (0 p : IsCh x) => (0 q : IsCh y) => RExpOf True t
110 | (&&) (Ch s) (Ch t) = Ch (intersection s t)
112 | public export %inline
113 | (||) : (x,y : RExpOf b t) -> (0 p : IsCh x) => (0 q : IsCh y) => RExpOf True t
114 | (||) (Ch s) (Ch t) = Ch (union s t)
117 | (<|>) : RExpOf b1 t -> RExpOf b2 t -> RExpOf (b1 && b2) t
118 | Ch x <|> Ch y = Ch (union x y)
122 | oneof : (rs : List (RExpOf True t)) -> (0 p : NonEmpty rs) => RExpOf True t
124 | oneof (r::t@(_::_)) = r <|> oneof t
126 | public export %inline
127 | (>>) : RExpOf b1 t -> RExpOf b2 t -> RExpOf (b1 || b2) t
130 | public export %inline
131 | eps : RExpOf False t
134 | public export %inline
135 | opt : RExpOf True t -> RExpOf False t
140 | chars : (cs : List Char) -> (0 p : NonEmpty cs) => RExp True
142 | chars (c::cs@(_::_)) = chr c >> chars cs
146 | charsLike : (cs : List Char) -> (0 p : NonEmpty cs) => RExp True
147 | charsLike [c] = charLike c
148 | charsLike (c::cs@(_::_)) = charLike c >> charsLike cs
152 | str : (s : String) -> (0 p : NonEmpty (unpack s)) => RExp True
153 | str s = chars (unpack s)
156 | public export %inline
157 | fromString : (s : String) -> (0 p : NonEmpty (unpack s)) => RExp True
162 | like : (s : String) -> (0 p : NonEmpty (unpack s)) => RExp True
163 | like s = charsLike (unpack s)
166 | pre : (s : String) -> (0 p : NonEmpty (unpack s)) => RExp b -> RExp True
167 | pre s r = str s >> r
169 | public export %inline
170 | star : RExpOf True t -> RExpOf False t
173 | public export %inline
174 | plus : RExpOf True t -> RExpOf True t
175 | plus x = x >> star x
178 | sep1 : (sep : RExpOf True t) -> RExpOf True t -> RExpOf True t
179 | sep1 sep x = x >> star (sep >> x)
182 | sep : (sep : RExpOf True t) -> RExpOf True t -> RExpOf False t
183 | sep s x = opt (sep1 s x)
196 | repeat : (n : Nat) -> RExpOf True t -> RExpOf (rep n) t
198 | repeat (S k) x = x >> repeat k x
202 | atmost : (n : Nat) -> RExpOf True t -> RExpOf False t
204 | atmost (S k) x = opt (x >> atmost k x)
208 | repeatRange : (m,n : Nat) -> RExpOf True t -> RExpOf (rep m) t
209 | repeatRange m n x = orF $
repeat m x >> atmost (n `minus` m) x
213 | atleast : (n : Nat) -> RExpOf True t -> RExpOf (rep n) t
214 | atleast n x = orF $
repeat n x >> star x
221 | public export %inline
232 | public export %inline
233 | range32 : Bits32 -> Bits32 -> RExp True
234 | range32 x y = Ch (range $
range x y)
237 | public export %inline
238 | range : Char -> Char -> RExp True
239 | range x y = Ch (range $
charRange x y)
242 | public export %inline
247 | posdigit : RExp True
248 | posdigit = Ch posdigit
251 | public export %inline
256 | public export %inline
261 | public export %inline
266 | public export %inline
267 | alphaNum : RExp True
268 | alphaNum = Ch alphaNum
272 | bindigit : RExp True
273 | bindigit = chr '0' <|> chr '1'
277 | octdigit : RExp True
278 | octdigit = range '0' '7'
284 | hexdigit : RExp True
285 | hexdigit = range '0' '9' <|> range 'a' 'f' <|> range 'A' 'F'
295 | public export %inline
296 | control : RExp True
297 | control = Ch control
300 | public export %inline
305 | public export %inline
310 | public export %inline
321 | binary = plus bindigit
326 | octal = plus octdigit
333 | decimal : RExp True
334 | decimal = chr '0' <|> (posdigit >> star digit)
340 | hexadecimal : RExp True
341 | hexadecimal = plus hexdigit
346 | integer : RExp True
347 | integer = opt '-' >> decimal
355 | natural : RExp True
357 | (like "0b" >> binary) <|>
358 | (like "0o" >> octal) <|>
359 | (like "0x" >> hexadecimal) <|>
369 | data ConstSize : (n : Nat) -> (x : RExpOf b t) -> Type where
372 | CS0 : ConstSize 0 Eps
375 | CSC : ConstSize 1 (Ch x)
379 | CSAnd : ConstSize m x -> ConstSize n y -> ConstSize (m+n) (And x y)
384 | CSOr : ConstSize n x -> ConstSize n y -> ConstSize n (Or x y)
389 | constSize : (x : RExpOf b t) -> Maybe (Subset Nat (`ConstSize` x))
390 | constSize Eps = Just (Element 0 CS0)
391 | constSize (Ch x) = Just (Element 1 CSC)
392 | constSize (And x y) = do
393 | Element m p1 <- constSize x
394 | Element n p2 <- constSize y
395 | pure (Element (m+n) (CSAnd p1 p2))
396 | constSize (Or x y) = do
397 | Element m p1 <- constSize x
398 | Element n p2 <- constSize y
400 | Just0 prf => pure (Element m (CSOr p1 (rewrite prf in p2)))
401 | Nothing0 => Nothing
402 | constSize (Star x) = Nothing
409 | -> {auto 0 prf : NonEmpty cs}
410 | -> ConstSize (length cs) (chars cs)
411 | charsConstSize [c] = CSC
412 | charsConstSize (c :: cs@(_::_)) = CSAnd CSC (charsConstSize cs)