1
0
forked from GitHub/gf-core

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
+3
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
+5
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)
+10 -10
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
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