9 | import Data.Bool.Rewrite
10 | import public Data.List
11 | import public Data.SnocList
12 | import public Data.Vect
13 | import public Text.Bounds
14 | import public Text.ParseError
15 | import public Text.Lex.Shift
23 | export infixl 8 <++>
26 | data Recognise : (strict : Bool) -> Type where
27 | Lift : Shifter b -> Recognise b
28 | (<+>) : Recognise b1 -> Recognise b2 -> Recognise (b1 || b2)
29 | (<++>) : Recognise True -> Inf (Recognise b) -> Recognise True
30 | (<|>) : Recognise b1 -> Lazy (Recognise b2) -> Recognise (b1 && b2)
36 | public export %inline
37 | swapOr : {0 x,y : _} -> Recognise (x || y) -> Recognise (y || x)
38 | swapOr = swapOr (\k => Recognise k)
40 | public export %inline
41 | orSame : {0 x : _} -> Recognise (x || x) -> Recognise x
42 | orSame = orSame (\k => Recognise k)
44 | public export %inline
45 | orTrue : {0 x : _} -> Recognise (x || True) -> Recognise True
46 | orTrue = orTrue (\k => Recognise k)
48 | public export %inline
49 | orFalse : {0 x : _} -> Recognise (x || False) -> Recognise x
50 | orFalse = orFalse (\k => Recognise k)
52 | public export %inline
53 | swapAnd : {0 x,y : _} -> Recognise (x && y) -> Recognise (y && x)
54 | swapAnd = swapAnd (\k => Recognise k)
56 | public export %inline
57 | andSame : {0 x : _} -> Recognise (x && x) -> Recognise x
58 | andSame = andSame (\k => Recognise k)
60 | public export %inline
61 | andTrue : {0 x : _} -> Recognise (x && True) -> Recognise x
62 | andTrue = andTrue (\k => Recognise k)
64 | public export %inline
65 | andFalse : {0 x : _} -> Recognise (x && False) -> Recognise False
66 | andFalse = andFalse (\k => Recognise k)
72 | public export %inline
73 | autoLift : AutoShift b -> Recognise b
74 | autoLift f = Lift $
\st,ts => orFalse $
f ts @{Same}
79 | Lexer = Recognise True
84 | -> (st : SnocList Char)
86 | -> (0 acc : SuffixAcc ts)
88 | run (Lift f) st ts _ = f st ts
89 | run (x <+> y) st ts a@(SA r) = case run x st ts a of
90 | Succ {pre} ts2 @{p} => case p of
91 | Same => run y pre ts a
93 | let su := suffix {b = True} (SH q)
94 | in swapOr $
run y pre ts2 r `trans` SH q
95 | Stop start errEnd r => Stop start errEnd r
96 | run (x <++> y) st ts a@(SA r) = case run x st ts a of
97 | Succ {pre} ts2 @{p} =>
98 | let su := suffix {b = True} p
99 | in swapOr $
run y pre ts2 r `trans` p
100 | Stop start errEnd r => Stop start errEnd r
101 | run (x <|> y) st ts a = run x st ts a <|> run y st ts a
104 | public export %inline
105 | empty : Recognise False
106 | empty = Lift $
\sc,cs => Succ cs
109 | public export %inline
110 | opt : Recognise True -> Recognise False
111 | opt l = l <|> empty
115 | expect : Recognise b -> Recognise False
116 | expect r = Lift $
\sc,cs => case run r sc cs suffixAcc of
118 | Stop x y z => Stop x y z
122 | reject : Recognise b -> Recognise False
123 | reject r = Lift $
\sc,cs => case run r sc cs suffixAcc of
125 | Succ {} => weaken $
fail sc cs
127 | public export %inline
128 | seqSame : Recognise b -> Recognise b -> Recognise b
129 | seqSame x y = orSame $
x <+> y
131 | public export %inline
132 | altSame : Recognise b -> Recognise b -> Recognise b
133 | altSame x y = andSame $
x <|> y
137 | fail : Recognise True
142 | many : Recognise True -> Recognise False
146 | some : Recognise True -> Recognise True
148 | many r = opt (some r)
150 | some r = r <++> many r
153 | public export %inline
154 | pred : (Char -> Bool) -> Recognise True
155 | pred f = autoLift $
one f
159 | public export %inline
160 | preds : (Char -> Bool) -> Recognise True
161 | preds f = autoLift $
takeWhile1 f
165 | public export %inline
166 | preds0 : (Char -> Bool) -> Recognise False
167 | preds0 = opt . preds
173 | -> {auto 0 prf : NonEmpty xs}
175 | concatMap f (x :: []) = f x
176 | concatMap f (x :: xs@(_ :: _)) = seqSame (f x) (concatMap f xs)
178 | public export %inline
179 | choiceMap : Foldable t => (a -> Recognise True) -> t a -> Recognise True
180 | choiceMap f = foldl (\v,e => altSame v $
f e) fail
182 | public export %inline
183 | choice : Foldable t => t (Recognise True) -> Recognise True
184 | choice = choiceMap id
191 | 0 TokenMap : (tokenType : Type) -> Type
192 | TokenMap tt = List (Recognise True, SnocList Char -> tt)
194 | public export %inline
195 | step : Recognise True -> (SnocList Char -> a) -> Tok True e a
196 | step x f cs = suffix f $
run x [<] cs suffixAcc
199 | first : (ps : TokenMap a) -> {auto 0 prf : NonEmpty ps} -> Tok True e a
200 | first ((f,g) :: []) cs = step f g cs
201 | first ((f,g) :: t@(_ :: _)) cs = step f g cs <|> first t cs