add parser and pretty printer for types

This commit is contained in:
krasimir
2008-10-20 07:52:14 +00:00
parent 418856d9bf
commit abe8da32fd
4 changed files with 78 additions and 10 deletions

View File

@@ -574,6 +574,7 @@ library
PGF.Parsing.FCFG.Incremental PGF.Parsing.FCFG.Incremental
PGF.Parsing.FCFG PGF.Parsing.FCFG
PGF.Expr PGF.Expr
PGF.Type
PGF.Raw.Parse PGF.Raw.Parse
PGF.Raw.Print PGF.Raw.Print
PGF.Raw.Convert PGF.Raw.Convert
@@ -680,6 +681,8 @@ executable gf
PGF PGF
PGF.CId PGF.CId
PGF.Data PGF.Data
PGF.Expr
PGF.Type
PGF.Macros PGF.Macros
PGF.Generate PGF.Generate
PGF.Linearize PGF.Linearize

View File

@@ -26,6 +26,10 @@ module PGF(
-- ** Category -- ** Category
Category, categories, startCat, Category, categories, startCat,
-- * Types
Type(..),
showType, readType,
-- * Expressions -- * Expressions
-- ** Tree -- ** Tree
@@ -64,6 +68,7 @@ import PGF.Paraphrase
import PGF.Macros import PGF.Macros
import PGF.Data import PGF.Data
import PGF.Expr import PGF.Expr
import PGF.Type
import PGF.Raw.Convert import PGF.Raw.Convert
import PGF.Raw.Parse import PGF.Raw.Parse
import PGF.Raw.Print (printTree) import PGF.Raw.Print (printTree)

View File

@@ -7,7 +7,7 @@ module PGF.Expr(readTree, showTree, pTree, ppTree,
Value(..), Env, eval, apply, Value(..), Env, eval, apply,
-- helpers -- helpers
pIdent,pStr pIdent,pStr,pFactor
) where ) where
import PGF.CId import PGF.CId
@@ -68,18 +68,9 @@ pExpr = RP.skipSpaces >> (pAbs RP.<++ pTerm RP.<++ pEqs)
where where
pTerm = fmap (foldl1 EApp) (RP.sepBy1 pFactor RP.skipSpaces) pTerm = fmap (foldl1 EApp) (RP.sepBy1 pFactor RP.skipSpaces)
pFactor = fmap EVar pCId
RP.<++ fmap ELit pLit
RP.<++ pMeta
RP.<++ RP.between (RP.char '(') (RP.char ')') pExpr
pAbs = do xs <- RP.between (RP.char '\\') (RP.skipSpaces >> RP.string "->") (RP.sepBy1 (RP.skipSpaces >> pCId) (RP.skipSpaces >> RP.char ',')) pAbs = do xs <- RP.between (RP.char '\\') (RP.skipSpaces >> RP.string "->") (RP.sepBy1 (RP.skipSpaces >> pCId) (RP.skipSpaces >> RP.char ','))
e <- pExpr e <- pExpr
return (foldr EAbs e xs) return (foldr EAbs e xs)
pMeta = do RP.char '?'
n <- fmap read (RP.munch1 isDigit)
return (EMeta n)
pEqs = fmap EEq $ pEqs = fmap EEq $
RP.between (RP.skipSpaces >> RP.char '{') RP.between (RP.skipSpaces >> RP.char '{')
@@ -92,6 +83,15 @@ pExpr = RP.skipSpaces >> (pAbs RP.<++ pTerm RP.<++ pEqs)
e <- pExpr e <- pExpr
return (Equ pats e) return (Equ pats e)
pFactor = fmap EVar pCId
RP.<++ fmap ELit pLit
RP.<++ pMeta
RP.<++ RP.between (RP.char '(') (RP.char ')') pExpr
where
pMeta = do RP.char '?'
n <- fmap read (RP.munch1 isDigit)
return (EMeta n)
pLit :: RP.ReadP Literal pLit :: RP.ReadP Literal
pLit = pNum RP.<++ liftM LStr pStr pLit = pNum RP.<++ liftM LStr pStr

60
src/PGF/Type.hs Normal file
View File

@@ -0,0 +1,60 @@
module PGF.Type ( readType, showType, pType, ppType ) where
import PGF.CId
import PGF.Data
import PGF.Expr
import Data.Char
import qualified Text.PrettyPrint as PP
import qualified Text.ParserCombinators.ReadP as RP
import Control.Monad
import Debug.Trace
-- | parses 'String' as an expression
readType :: String -> Maybe Type
readType s = case [x | (x,cs) <- RP.readP_to_S pType s, all isSpace cs] of
[x] -> Just x
_ -> Nothing
-- | renders type as 'String'
showType :: Type -> String
showType = PP.render . ppType 0
pType = do
RP.skipSpaces
hyps <- RP.sepBy (pHypo >>= \h -> RP.string "->" >> return h) RP.skipSpaces
RP.skipSpaces
(cat,args) <- pAtom
return (DTyp hyps cat args)
where
pHypo =
do (cat,args) <- pAtom
return (Hyp wildCId (DTyp [] cat args))
RP.<++
(RP.between (RP.char '(') (RP.char ')') $ do
var <- RP.option wildCId $ do
v <- pIdent
RP.skipSpaces
RP.string ":"
return (mkCId v)
ty <- pType
return (Hyp var ty))
pAtom = do
cat <- pIdent
RP.skipSpaces
args <- RP.sepBy pFactor RP.skipSpaces
return (mkCId cat, args)
ppType d (DTyp ctxt cat args)
| null ctxt = ppRes cat args
| otherwise = ppParens (d > 0) (foldr ppCtxt (ppRes cat args) ctxt)
where
ppCtxt (Hyp x typ) doc
| x == wildCId = ppType 1 typ PP.<+> PP.text "->" PP.<+> doc
| otherwise = PP.parens (PP.text (prCId x) PP.<+> PP.char ':' PP.<+> ppType 0 typ) PP.<+> PP.text "->" PP.<+> doc
ppRes cat es = PP.text (prCId cat) PP.<+> PP.hsep (map (ppExpr 2) es)
ppParens True = PP.parens
ppParens False = id