{-# LANGUAGE TypeFamilies #-}
import Control.Monad (mzero)
class Pushdown m where
data State m :: *
data Sigma m :: *
data Gamma m :: *
startState :: State m
startGamma :: Gamma m
delta :: ID m -> [ID m]
endState :: State m -> Bool
-- instantaneous description
type ID m = (State m, [Sigma m], [Gamma m])
endID :: Pushdown m => ID m -> Bool
endID (q, xs, ps) = null ps || endState q && null xs
runPushdown :: Pushdown m => [Sigma m] -> [ID m]
runPushdown xs =
go [(startState, xs, [startGamma])]
where
go ids = do
id@(_, _, ps) <- ids
case go $ delta id of
[] ->
if endID id then
return id
else
mzero
ids' ->
go ids'
---
data IdenC
mayusculas = map Carac $ ['A'..'Z']
minusculas = map Carac $ ['a'..'z']
letra = minusculas ++ mayusculas
digito = map Carac $ ['0'..'9']
sigma = Carac '_' : digito ++ letra
instance Pushdown IdenC where
data State IdenC = Q1 | Q2 deriving Show
newtype Sigma IdenC = Carac Char deriving (Show, Eq)
data Gamma IdenC = Z deriving Show
startState = Q1
startGamma = Z
delta (Q1, x:xs, ps)
| x `elem` letra = [(Q2, xs, ps)]
delta (Q2, x:xs, ps)
| x `elem` sigma = [(Q2, xs, ps)]
delta (Q2, [], Z:ps) = [(Q2, [], ps)]
delta _ = []
endState _ = False