Safe Haskell | None |
---|---|
Language | Haskell98 |
- The required type classes. Each class does its own thing.
- Terminates the stack of arguments
- A single character terminal. Using unboxed vector to hold the input. Note
- Empty and non-empty tables.
- Parses an empty subword.
- Parsing subwords with restriced size. Both min- and max-size are given
- Backtracking tables.
- Build complex stacks
- combinators
- Apply function
f
in '(<<<)'
HINTS for writing your own (Non-) terminals:
- ALWAYS provide types for local functions of
mkStream
andmkStreamInner
. Otherwise stream-fusion gets confused and doesn't optimize. (Observable in core by looking forLeft
,RIght
constructors andSPEC
constructors.
- class Build x where
- type BuildStack x :: *
- build :: x -> BuildStack x
- class StreamElement x where
- data StreamElm x :: *
- type StreamTopIdx x :: *
- type StreamArg x :: *
- getTopIdx :: StreamElm x -> StreamTopIdx x
- getArg :: StreamElm x -> StreamArg x
- class StreamConstraint x => MkStream m x where
- type StreamConstraint x :: Constraint
- mkStream :: StreamConstraint x => x -> (Int, Int) -> Stream m (StreamElm x)
- mkStreamInner :: StreamConstraint x => x -> (Int, Int) -> Stream m (StreamElm x)
- data None = None
- data ArgZ = ArgZ
- data Chr e = Chr !(Vector e)
- data E
- data N
- class TransToN t where
- class TblType tt where
- initDeltaIdx :: tt -> Int
- data Tbl c es = Tbl !es
- data MTbl c es = MTbl !es
- mtblN :: es -> MTbl N es
- mtblE :: es -> MTbl E es
- tNtoE :: Tbl N x -> Tbl E x
- tEtoN :: Tbl E x -> Tbl N x
- data Empty = Empty
- data RestrictedRegion e = RRegion !Int !Int !(Vector e)
- data BTtbl c t g = BTtbl t g
- bttblN :: t -> g -> BTtbl N t g
- bttblE :: t -> g -> BTtbl E t g
- type BTfun m b = (Int, Int) -> m (Stream m b)
- (<<<) :: (Build x, StreamElement (BuildStack x), MkStream m (BuildStack x), Apply (StreamArg (BuildStack x) -> b), Monad m) => Fun (StreamArg (BuildStack x) -> b) -> x -> (Int, Int) -> Stream m b
- (|||) :: Monad m => (t -> Stream m a) -> (t -> Stream m a) -> t -> Stream m a
- (...) :: (t1 -> s) -> (s -> t) -> t1 -> t
- (..@) :: (t1 -> s) -> (t1 -> s -> t) -> t1 -> t
- (~~) :: a -> b -> (a, b)
- (%) :: a -> b -> (a, b)
- class Apply x where
The required type classes. Each class does its own thing.
The Build
class. Combines the arguments into a stack before they are
turned into a stream.
To use, simply write "instance Build MyDataCtor" as we have sensible default instances.
Nothing
type BuildStack x :: * Source
The stack of arguments we are building.
build :: x -> BuildStack x Source
The default is for the left-most element.
Given an element, create the stack.
class StreamElement x where Source
The stream element. Creates a type-level recursive data type containing the extracted arguments.
one element of the stream, recursively defined
type StreamTopIdx x :: * Source
top-most index of the stream -- typically int
complete, recursively defined argument of the stream
getTopIdx :: StreamElm x -> StreamTopIdx x Source
Given a stream element, we extract the top-most idx
getArg :: StreamElm x -> StreamArg x Source
extract the recursively defined argument in a well-defined way for apply
StreamElement Empty | |
StreamElement None | |
(Monad m, StreamElement x, TblType c) => StreamElement ((:.) x (BTtbl c (Arr0 DIM2 e) (BTfun m b))) | |
StreamElement x => StreamElement ((:.) x (RestrictedRegion e)) | |
(StreamElement x, MPrimArrayOps marr DIM2 e, TblType c) => StreamElement ((:.) x (MTbl c (marr s DIM2 e))) | |
(StreamElement x, PrimArrayOps arr DIM2 e, TblType c) => StreamElement ((:.) x (Tbl c (arr DIM2 e))) | |
StreamElement x => StreamElement ((:.) x (Chr e)) |
class StreamConstraint x => MkStream m x where Source
Given the arguments, creates a stream of StreamElement
s.
type StreamConstraint x :: Constraint Source
mkStream :: StreamConstraint x => x -> (Int, Int) -> Stream m (StreamElm x) Source
mkStreamInner :: StreamConstraint x => x -> (Int, Int) -> Stream m (StreamElm x) Source
Monad m => MkStream m Empty | |
Monad m => MkStream m None | |
(Monad m, MkStream m x, StreamElement x, Unbox e, (~) * (StreamTopIdx x) Int, TblType c) => MkStream m ((:.) x (BTtbl c (Arr0 DIM2 e) (BTfun m b))) | |
(Monad m, MkStream m x, StreamElement x, (~) * (StreamTopIdx x) Int, Unbox e) => MkStream m ((:.) x (RestrictedRegion e)) | |
(Monad m, PrimMonad m, MkStream m x, StreamElement x, (~) * (StreamTopIdx x) Int, MPrimArrayOps marr DIM2 e, TblType c, (~) * s (PrimState m)) => MkStream m ((:.) x (MTbl c (marr s DIM2 e))) | |
(Monad m, MkStream m x, StreamElement x, (~) * (StreamTopIdx x) Int, PrimArrayOps arr DIM2 e, TblType c) => MkStream m ((:.) x (Tbl c (arr DIM2 e))) | |
(Monad m, MkStream m x, StreamElement x, (~) * (StreamTopIdx x) Int, Unbox e) => MkStream m ((:.) x (Chr e)) |
Terminates the stack of arguments
Very simple data ctor
For CORE-language, we have our own Arg-terminator
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i) j) k) l) m) n) o -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i) j) k) l) m) n -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i) j) k) l) m -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i) j) k) l -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i) j) k -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i) j -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d -> res) | |
Apply ((:.) ((:.) ((:.) ArgZ a) b) c -> res) | |
Apply ((:.) ((:.) ArgZ a) b -> res) | |
Apply ((:.) ArgZ a -> res) | |
type Fun ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i) j) k) l) m) n) o -> res) = a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l -> m -> n -> o -> res | |
type Fun ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i) j) k) l) m) n -> res) = a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l -> m -> n -> res | |
type Fun ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i) j) k) l) m -> res) = a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l -> m -> res | |
type Fun ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i) j) k) l -> res) = a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l -> res | |
type Fun ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i) j) k -> res) = a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> res | |
type Fun ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i) j -> res) = a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> res | |
type Fun ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i -> res) = a -> b -> c -> d -> e -> f -> g -> h -> i -> res | |
type Fun ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h -> res) = a -> b -> c -> d -> e -> f -> g -> h -> res | |
type Fun ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g -> res) = a -> b -> c -> d -> e -> f -> g -> res | |
type Fun ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f -> res) = a -> b -> c -> d -> e -> f -> res | |
type Fun ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e -> res) = a -> b -> c -> d -> e -> res | |
type Fun ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d -> res) = a -> b -> c -> d -> res | |
type Fun ((:.) ((:.) ((:.) ArgZ a) b) c -> res) = a -> b -> c -> res | |
type Fun ((:.) ((:.) ArgZ a) b -> res) = a -> b -> res | |
type Fun ((:.) ArgZ a -> res) = a -> res |
A single character terminal. Using unboxed vector to hold the input. Note
(Monad m, MkStream m x, StreamElement x, (~) * (StreamTopIdx x) Int, Unbox e) => MkStream m ((:.) x (Chr e)) | |
Build (Chr e) | |
StreamElement x => StreamElement ((:.) x (Chr e)) | |
type BuildStack (Chr e) = (:.) None (Chr e) | |
type StreamConstraint ((:.) x (Chr e)) = () | |
data StreamElm ((:.) x (Chr e)) = SeChr !(StreamElm x) !Int !e | |
type StreamTopIdx ((:.) x (Chr e)) = Int | |
type StreamArg ((:.) x (Chr e)) = (:.) (StreamArg x) e |
Empty and non-empty tables.
Used by the instances below for index calculations.
initDeltaIdx :: tt -> Int Source
Immutable tables
Tbl !es |
(Monad m, MkStream m x, StreamElement x, (~) * (StreamTopIdx x) Int, PrimArrayOps arr DIM2 e, TblType c) => MkStream m ((:.) x (Tbl c (arr DIM2 e))) | |
TransToN (Tbl c es) | |
(StreamElement x, PrimArrayOps arr DIM2 e, TblType c) => StreamElement ((:.) x (Tbl c (arr DIM2 e))) | |
Build (Tbl c es) | |
type TransTo (Tbl c es) = Tbl N es | |
type StreamConstraint ((:.) x (Tbl c (arr DIM2 e))) = () | |
data StreamElm ((:.) x (Tbl c (arr DIM2 e))) = SeTbl !(StreamElm x) !Int !e | |
type StreamTopIdx ((:.) x (Tbl c (arr DIM2 e))) = Int | |
type StreamArg ((:.) x (Tbl c (arr DIM2 e))) = (:.) (StreamArg x) e | |
type BuildStack (Tbl c es) = (:.) None (Tbl c es) |
Mutable tables in some monad.
MTbl !es |
(Monad m, PrimMonad m, MkStream m x, StreamElement x, (~) * (StreamTopIdx x) Int, MPrimArrayOps marr DIM2 e, TblType c, (~) * s (PrimState m)) => MkStream m ((:.) x (MTbl c (marr s DIM2 e))) | |
TransToN (MTbl c es) | |
(StreamElement x, MPrimArrayOps marr DIM2 e, TblType c) => StreamElement ((:.) x (MTbl c (marr s DIM2 e))) | |
Build (MTbl c es) | |
type TransTo (MTbl c es) = MTbl N es | |
type StreamConstraint ((:.) x (MTbl c (marr s DIM2 e))) = () | |
data StreamElm ((:.) x (MTbl c (marr s DIM2 e))) = SeMTbl !(StreamElm x) !Int !e | |
type StreamTopIdx ((:.) x (MTbl c (marr s DIM2 e))) = Int | |
type StreamArg ((:.) x (MTbl c (marr s DIM2 e))) = (:.) (StreamArg x) e | |
type BuildStack (MTbl c es) = (:.) None (MTbl c es) |
Some convenience functions.
Parses an empty subword.
The empty subword. Can not be part of a more complex RHS for obvious reasons: "S -> E S" doesn't make sense. Used in some grammars as the base case.
Parsing subwords with restriced size. Both min- and max-size are given
data RestrictedRegion e Source
(Monad m, MkStream m x, StreamElement x, (~) * (StreamTopIdx x) Int, Unbox e) => MkStream m ((:.) x (RestrictedRegion e)) | |
Build (RestrictedRegion e) | |
StreamElement x => StreamElement ((:.) x (RestrictedRegion e)) | |
type BuildStack (RestrictedRegion e) = (:.) None (RestrictedRegion e) | |
type StreamConstraint ((:.) x (RestrictedRegion e)) = () | |
data StreamElm ((:.) x (RestrictedRegion e)) = SeResRegion !(StreamElm x) !Int (Vector e) | |
type StreamTopIdx ((:.) x (RestrictedRegion e)) = Int | |
type StreamArg ((:.) x (RestrictedRegion e)) = (:.) (StreamArg x) (Vector e) |
Backtracking tables.
The backtracking table 'BTtbl" captures a DP table and the function used to fill it.
BTtbl t g |
(Monad m, MkStream m x, StreamElement x, Unbox e, (~) * (StreamTopIdx x) Int, TblType c) => MkStream m ((:.) x (BTtbl c (Arr0 DIM2 e) (BTfun m b))) | |
(Monad m, StreamElement x, TblType c) => StreamElement ((:.) x (BTtbl c (Arr0 DIM2 e) (BTfun m b))) | |
TransToN (BTtbl c t g) | |
Build (BTtbl c t g) | |
type StreamConstraint ((:.) x (BTtbl c (Arr0 DIM2 e) (BTfun m b))) = () | |
data StreamElm ((:.) x (BTtbl c (Arr0 DIM2 e) (BTfun m b))) = SeBTtbl !(StreamElm x) !Int !e (m (Stream m b)) | |
type StreamTopIdx ((:.) x (BTtbl c (Arr0 DIM2 e) (BTfun m b))) = Int | |
type StreamArg ((:.) x (BTtbl c (Arr0 DIM2 e) (BTfun m b))) = (:.) (StreamArg x) (e, m (Stream m b)) | |
type TransTo (BTtbl c t g) = BTtbl N t g | |
type BuildStack (BTtbl c t g) = (:.) None (BTtbl c t g) |
type BTfun m b = (Int, Int) -> m (Stream m b) Source
The backtracking function, given our index pair, return a stream of backtracked results. (Return as in we are in a monad).
TODO Should this be "(Int,Int) -> m (SM.Stream Id b)" or are there cases where we'd like to have monadic effects on the "b"s?
Build complex stacks
combinators
(<<<) :: (Build x, StreamElement (BuildStack x), MkStream m (BuildStack x), Apply (StreamArg (BuildStack x) -> b), Monad m) => Fun (StreamArg (BuildStack x) -> b) -> x -> (Int, Int) -> Stream m b infixl 8 Source
Apply function f
in '(<<<)'
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i) j) k) l) m) n) o -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i) j) k) l) m) n -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i) j) k) l) m -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i) j) k) l -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i) j) k -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i) j -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h) i -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g) h -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f) g -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e) f -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d) e -> res) | |
Apply ((:.) ((:.) ((:.) ((:.) ArgZ a) b) c) d -> res) | |
Apply ((:.) ((:.) ((:.) ArgZ a) b) c -> res) | |
Apply ((:.) ((:.) ArgZ a) b -> res) | |
Apply ((:.) ArgZ a -> res) |