forked from GitHub/gf-core
Two improvements in the pgf-shell example
1. Like pgf-translate, it now shows one result at a time, press Enter to get more results. 2. You can load a new grammar with the command 'i <path-to-pgf>'
This commit is contained in:
2
gf.cabal
2
gf.cabal
@@ -261,7 +261,7 @@ executable pgf-shell
|
|||||||
buildable: False
|
buildable: False
|
||||||
main-is: pgf-shell.hs
|
main-is: pgf-shell.hs
|
||||||
hs-source-dirs: src/runtime/haskell-bind/examples
|
hs-source-dirs: src/runtime/haskell-bind/examples
|
||||||
build-depends: gf, base, containers
|
build-depends: gf, base, containers, mtl, lifted-base
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
if impl(ghc>=7.0)
|
if impl(ghc>=7.0)
|
||||||
ghc-options: -rtsopts
|
ghc-options: -rtsopts
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
{-# LANGUAGE CPP #-}
|
|
||||||
-- | pgf-shell: A simple shell to illustrate the use of the Haskell binding
|
-- | pgf-shell: A simple shell to illustrate the use of the Haskell binding
|
||||||
-- to the C implementation of the PGF run-time system.
|
-- to the C implementation of the PGF run-time system.
|
||||||
--
|
--
|
||||||
@@ -9,6 +8,8 @@
|
|||||||
-- * translate: t <lang> <lang> <text>
|
-- * translate: t <lang> <lang> <text>
|
||||||
|
|
||||||
import Control.Monad(forever)
|
import Control.Monad(forever)
|
||||||
|
import Control.Monad.State(evalStateT,put,get,gets,liftIO)
|
||||||
|
import Control.Exception.Lifted(catch)
|
||||||
import Data.Char(isSpace)
|
import Data.Char(isSpace)
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import System.IO(hFlush,stdout)
|
import System.IO(hFlush,stdout)
|
||||||
@@ -25,48 +26,64 @@ getPGF _ = putStrLn "Usage: pgf-shell <path to pgf>"
|
|||||||
|
|
||||||
pgfShell pgf =
|
pgfShell pgf =
|
||||||
do putStrLn . unwords . M.keys $ languages pgf
|
do putStrLn . unwords . M.keys $ languages pgf
|
||||||
forever $ do performGC
|
flip evalStateT (pgf,[]) $ forever $ do liftIO performGC
|
||||||
putStr "> "; hFlush stdout
|
puts "> "; liftIO $ hFlush stdout
|
||||||
execute pgf =<< readLn
|
execute =<< liftIO readLn
|
||||||
|
|
||||||
execute pgf cmd =
|
execute cmd =
|
||||||
case cmd of
|
case cmd of
|
||||||
L lang tree -> do c <- getConcr' pgf lang
|
L lang tree -> do pgf <- gets fst
|
||||||
putStrLn $ linearize c tree
|
c <- getConcr' pgf lang
|
||||||
P lang s -> do c <- getConcr' pgf lang
|
put (pgf,[])
|
||||||
|
putln $ linearize c tree
|
||||||
|
P lang s -> do pgf <- gets fst
|
||||||
|
c <- getConcr' pgf lang
|
||||||
case parse c (startCat pgf) s of
|
case parse c (startCat pgf) s of
|
||||||
Left tok -> putStrLn ("parse error: "++tok)
|
Left tok -> do put (pgf,[])
|
||||||
Right ts -> printl ts
|
putln ("Parse error: "++tok)
|
||||||
T from to s -> do cfrom <- getConcr' pgf from
|
Right ts -> do put (pgf,map show ts)
|
||||||
|
pop
|
||||||
|
T from to s -> do pgf <- gets fst
|
||||||
|
cfrom <- getConcr' pgf from
|
||||||
cto <- getConcr' pgf to
|
cto <- getConcr' pgf to
|
||||||
putl [linearize cto t|(t,_)<-case parse cfrom (startCat pgf) s of
|
case parse cfrom (startCat pgf) s of
|
||||||
Left _ -> []
|
Left tok -> do put (pgf,[])
|
||||||
Right ts -> ts]
|
putln ("Parse error: "++tok)
|
||||||
_ -> putStrLn "Huh?"
|
Right ts -> do put (pgf,map (linearize cto.fst) ts)
|
||||||
`catch` print
|
pop
|
||||||
|
I path -> do pgf <- liftIO (readPGF path)
|
||||||
|
putln . unwords . M.keys $ languages pgf
|
||||||
|
put (pgf,[])
|
||||||
|
Empty -> pop
|
||||||
|
Unknown s -> putln ("Unknown command: "++s)
|
||||||
|
`catch` (liftIO . print . (id::IOError->IOError))
|
||||||
|
|
||||||
|
pop = do (pgf,ls) <- get
|
||||||
|
let (ls1,ls2) = splitAt 1 ls
|
||||||
|
putl ls1
|
||||||
|
put (pgf,ls2)
|
||||||
|
|
||||||
getConcr' pgf lang =
|
getConcr' pgf lang =
|
||||||
maybe (fail $ "Concrete syntax not found: "++show lang) return $
|
maybe (fail $ "Concrete syntax not found: "++show lang) return $
|
||||||
Map.lookup lang (languages pgf)
|
Map.lookup lang (languages pgf)
|
||||||
|
|
||||||
printl xs = putl $ map show xs
|
printl xs = liftIO $ putl $ map show xs
|
||||||
putl = putStr . unlines
|
putl ls = liftIO . putStr $ unlines ls
|
||||||
|
putln s = liftIO $ putStrLn s
|
||||||
|
puts s = liftIO $ putStr s
|
||||||
|
|
||||||
-- | Abstracy syntax of shell commands
|
-- | Abstracy syntax of shell commands
|
||||||
data Command = P String String | L String Expr | T String String String deriving Show
|
data Command = P String String | L String Expr | T String String String
|
||||||
|
| I FilePath | Empty | Unknown String
|
||||||
|
deriving Show
|
||||||
|
|
||||||
-- | Shell command parser
|
-- | Shell command parser
|
||||||
instance Read Command where
|
instance Read Command where
|
||||||
readsPrec _ s =
|
readsPrec _ s =
|
||||||
[(P l r2,"") | ("p",r1)<-lex s,
|
take 1 $
|
||||||
(l,r2) <- lex r1]
|
[(P l r2,"") | ("p",r1)<-lex s, (l,r2) <- lex r1]
|
||||||
++ [(L l t,"") | ("l",r1)<-lex s,
|
++ [(L l t,"") | ("l",r1)<-lex s, (l,r2)<- lex r1, Just t<-[readExpr r2]]
|
||||||
(l,r2)<- lex r1,
|
++ [(T l1 l2 r3,"") | ("t",r1)<-lex s, (l1,r2)<-lex r1, (l2,r3)<-lex r2]
|
||||||
Just t<-[readExpr r2]]
|
++ [(I (dropWhile isSpace r),"") | ("i",r)<-lex s]
|
||||||
++ [(T l1 l2 r3,"") | ("t",r1)<-lex s,
|
++ [(Empty,"") | ("","") <- lex s]
|
||||||
(l1,r2)<-lex r1,
|
++ [(Unknown s,"")]
|
||||||
(l2,r3)<-lex r2]
|
|
||||||
|
|
||||||
#if MIN_VERSION_base(4,6,0)
|
|
||||||
catch = S.catchIOError
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ library
|
|||||||
build-depends: base >=4.3, bytestring >=0.9,
|
build-depends: base >=4.3, bytestring >=0.9,
|
||||||
containers
|
containers
|
||||||
-- hs-source-dirs:
|
-- hs-source-dirs:
|
||||||
|
default-language: Haskell2010
|
||||||
build-tools: hsc2hs
|
build-tools: hsc2hs
|
||||||
|
|
||||||
extra-libraries: gu pgf
|
extra-libraries: gu pgf
|
||||||
cc-options: -std=c99
|
cc-options: -std=c99
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
@@ -30,7 +32,7 @@ library
|
|||||||
executable pgf-shell
|
executable pgf-shell
|
||||||
main-is: pgf-shell.hs
|
main-is: pgf-shell.hs
|
||||||
hs-source-dirs: examples
|
hs-source-dirs: examples
|
||||||
build-depends: base, pgf2-bind, containers
|
build-depends: base, pgf2-bind, containers, mtl, lifted-base
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
if impl(ghc>=7.0)
|
if impl(ghc>=7.0)
|
||||||
ghc-options: -rtsopts
|
ghc-options: -rtsopts
|
||||||
|
|||||||
Reference in New Issue
Block a user