module PP.Builder
(
LrTable(..)
, action
, action'
, LrAction(..)
, LrCollection(..)
, LrSet(..)
, LrBuilder(..)
, NfaGraph(..)
, NfaNode(..)
, NfaSymbol(..)
, NfaBuilder(..)
, DfaGraph(..)
, DfaNode(..)
, DfaSymbol(..)
, DfaBuilder(..)
) where
import Control.Monad
import Data.Binary
import qualified Data.Graph.Inductive.Graph as Gr
import qualified Data.Graph.Inductive.PatriciaTree as Gr
import qualified Data.Map.Strict as Map
import Data.Maybe
import qualified Data.Set as Set
import qualified Data.Vector as Vector
import PP.Lexer (OToken (..))
import PP.Rule
type LrTable = Map.Map (Int, Rule) LrAction
action :: LrTable -> Int -> Rule -> LrAction
action t i r = fromMaybe LrError (Map.lookup (i, r) t)
action' :: LrTable -> Int -> [OToken] -> LrAction
action' t i [] = action t i Empty
action' t i (OToken1 []:_) = action t i Empty
action' t i (OToken1 (x:_):_) = action t i $ Term x
action' t i (OToken2 _ s:_) = action t i $ TermToken s
data LrAction
= LrShift Int
| LrReduce Rule
| LrGoto Int
| LrError
| LrAccept
deriving(Eq)
instance Show LrAction where
show (LrShift i) = "shift " ++ show i
show (LrReduce r) = "reduce " ++ show r
show (LrGoto i) = "goto " ++ show i
show LrError = "error"
show LrAccept = "accept"
instance Binary LrAction where
put (LrShift i) = putWord8 0 >> put i
put (LrReduce r) = putWord8 1 >> put r
put (LrGoto i) = putWord8 2 >> put i
put LrError = putWord8 3
put LrAccept = putWord8 4
get = do
tag <- getWord8
case tag of
0 -> fmap LrShift get
1 -> fmap LrReduce get
2 -> fmap LrGoto get
3 -> return LrError
4 -> return LrAccept
type LrCollection item = Vector.Vector (LrSet item)
instance (Binary item) => Binary (LrCollection item) where
put c = put $ Vector.toList c
get = fmap Vector.fromList get
type LrSet item = Set.Set item
class Ord item => LrBuilder item where
collection :: RuleSet -> FirstSet -> LrCollection item
table :: LrCollection item -> Either [String] LrTable
type NfaGraph = Gr.Gr NfaNode NfaSymbol
data NfaNode = NfaInitial | NfaNode | NfaFinal String deriving (Eq, Ord, Show, Read)
data NfaSymbol = NfaValue Char | NfaEmpty deriving (Eq, Ord, Show, Read)
class NfaBuilder from where
buildNfa :: from -> NfaGraph
buildNfa' :: String -> from -> NfaGraph
type DfaGraph = Gr.Gr DfaNode DfaSymbol
data DfaNode = DfaInitial | DfaNode | DfaFinal String deriving (Eq, Ord, Show, Read)
newtype DfaSymbol = DfaValue Char deriving (Eq, Ord, Read)
instance Show DfaSymbol where
show (DfaValue c) = show c
instance Binary DfaGraph where
put g = put (Gr.labNodes g) >> put (Gr.labEdges g)
get = liftM2 Gr.mkGraph get get
instance Binary DfaNode where
put DfaInitial = putWord8 0
put DfaNode = putWord8 1
put (DfaFinal s) = putWord8 2 >> put s
get = do
tag <- getWord8
case tag of
0 -> return DfaInitial
1 -> return DfaNode
2 -> fmap DfaFinal get
instance Binary DfaSymbol where
put (DfaValue c) = put c
get = fmap DfaValue get
class DfaBuilder from where
buildDfa :: from -> DfaGraph