forked from GitHub/gf-core
drop the haskell runtime, part 2
This commit is contained in:
21
gf.cabal
21
gf.cabal
@@ -67,29 +67,15 @@ flag network-uri
|
|||||||
description: Get Network.URI from the network-uri package
|
description: Get Network.URI from the network-uri package
|
||||||
default: True
|
default: True
|
||||||
|
|
||||||
--flag new-comp
|
|
||||||
-- Description: Make -new-comp the default
|
|
||||||
-- Default: True
|
|
||||||
|
|
||||||
flag c-runtime
|
|
||||||
Description: Include functionality from the C run-time library (which must be installed already)
|
|
||||||
Default: False
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
executable gf
|
executable gf
|
||||||
hs-source-dirs: src/programs, src/runtime/haskell/binary
|
hs-source-dirs: src/programs
|
||||||
main-is: gf-main.hs
|
main-is: gf-main.hs
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
build-depends: base, filepath, directory, time, time-compat, old-locale, pretty, mtl, array, random,
|
build-depends: pgf2, base, filepath, directory, time, time-compat, old-locale, pretty, mtl, array, random,
|
||||||
process, haskeline, parallel>=3, exceptions, bytestring, utf8-string, containers
|
process, haskeline, parallel>=3, exceptions, bytestring, utf8-string, containers
|
||||||
ghc-options: -threaded
|
ghc-options: -threaded
|
||||||
|
|
||||||
if flag(c-runtime)
|
|
||||||
build-depends: pgf2
|
|
||||||
else
|
|
||||||
build-depends: pgf
|
|
||||||
|
|
||||||
if impl(ghc>=7.0)
|
if impl(ghc>=7.0)
|
||||||
ghc-options: -rtsopts -with-rtsopts=-I5
|
ghc-options: -rtsopts -with-rtsopts=-I5
|
||||||
if impl(ghc<7.8)
|
if impl(ghc<7.8)
|
||||||
@@ -223,9 +209,6 @@ executable gf
|
|||||||
Data.Binary.Builder
|
Data.Binary.Builder
|
||||||
Data.Binary.IEEE754
|
Data.Binary.IEEE754
|
||||||
|
|
||||||
if flag(c-runtime)
|
|
||||||
cpp-options: -DC_RUNTIME
|
|
||||||
|
|
||||||
if flag(server)
|
if flag(server)
|
||||||
build-depends: httpd-shed>=0.4.0.3, network>=2.3 && <2.7, json,
|
build-depends: httpd-shed>=0.4.0.3, network>=2.3 && <2.7, json,
|
||||||
cgi>=3001.2.2.0
|
cgi>=3001.2.2.0
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import qualified Data.Map as Map
|
|||||||
import Data.List(nub,mapAccumL)
|
import Data.List(nub,mapAccumL)
|
||||||
import Data.Maybe(fromMaybe)
|
import Data.Maybe(fromMaybe)
|
||||||
|
|
||||||
#if C_RUNTIME
|
|
||||||
generateByteCode :: SourceGrammar -> Int -> [L Equation] -> [[Instr]]
|
generateByteCode :: SourceGrammar -> Int -> [L Equation] -> [[Instr]]
|
||||||
generateByteCode gr arity eqs =
|
generateByteCode gr arity eqs =
|
||||||
let (bs,instrs) = compileEquations gr arity (arity+1) is
|
let (bs,instrs) = compileEquations gr arity (arity+1) is
|
||||||
@@ -302,7 +301,3 @@ freeVars xs e = collectOp (freeVars xs) e
|
|||||||
push_is :: Int -> Int -> [IVal] -> [IVal]
|
push_is :: Int -> Int -> [IVal] -> [IVal]
|
||||||
push_is i 0 is = is
|
push_is i 0 is = is
|
||||||
push_is i n is = ARG_VAR i : push_is (i-1) (n-1) is
|
push_is i n is = ARG_VAR i : push_is (i-1) (n-1) is
|
||||||
|
|
||||||
#else
|
|
||||||
generateByteCode = error "generateByteCode is not implemented"
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -14,9 +14,3 @@ buildInfo =
|
|||||||
#ifdef SERVER_MODE
|
#ifdef SERVER_MODE
|
||||||
++" server"
|
++" server"
|
||||||
#endif
|
#endif
|
||||||
#ifdef NEW_COMP
|
|
||||||
++" new-comp"
|
|
||||||
#endif
|
|
||||||
#ifdef C_RUNTIME
|
|
||||||
++" c-runtime"
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -12,9 +12,6 @@ module GF.Infra.SIO(
|
|||||||
newStdGen,print,putStr,putStrLn,
|
newStdGen,print,putStr,putStrLn,
|
||||||
-- ** Specific to GF
|
-- ** Specific to GF
|
||||||
importGrammar,importSource,
|
importGrammar,importSource,
|
||||||
#ifdef C_RUNTIME
|
|
||||||
readPGF2,
|
|
||||||
#endif
|
|
||||||
putStrLnFlush,runInterruptibly,lazySIO,
|
putStrLnFlush,runInterruptibly,lazySIO,
|
||||||
-- * Restricted accesss to arbitrary (potentially unsafe) IO operations
|
-- * Restricted accesss to arbitrary (potentially unsafe) IO operations
|
||||||
-- | If the environment variable GF_RESTRICTED is defined, these
|
-- | If the environment variable GF_RESTRICTED is defined, these
|
||||||
@@ -39,9 +36,6 @@ import qualified System.Random as IO(newStdGen)
|
|||||||
import qualified GF.Infra.UseIO as IO(getLibraryDirectory)
|
import qualified GF.Infra.UseIO as IO(getLibraryDirectory)
|
||||||
import qualified GF.System.Signal as IO(runInterruptibly)
|
import qualified GF.System.Signal as IO(runInterruptibly)
|
||||||
import qualified GF.Command.Importing as GF(importGrammar, importSource)
|
import qualified GF.Command.Importing as GF(importGrammar, importSource)
|
||||||
#ifdef C_RUNTIME
|
|
||||||
import qualified PGF2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
-- * The SIO monad
|
-- * The SIO monad
|
||||||
|
|
||||||
@@ -123,7 +117,3 @@ lazySIO = lift1 lazyIO
|
|||||||
|
|
||||||
importGrammar pgf opts files = lift0 $ GF.importGrammar pgf opts files
|
importGrammar pgf opts files = lift0 $ GF.importGrammar pgf opts files
|
||||||
importSource opts files = lift0 $ GF.importSource opts files
|
importSource opts files = lift0 $ GF.importSource opts files
|
||||||
|
|
||||||
#ifdef C_RUNTIME
|
|
||||||
readPGF2 = lift0 . PGF2.readPGF
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ handle logLn documentroot state0 cache execute1 stateVar
|
|||||||
|
|
||||||
translatePath rpath = root</>rpath -- hmm, check for ".."
|
translatePath rpath = root</>rpath -- hmm, check for ".."
|
||||||
|
|
||||||
versionInfo (c1,c2) =
|
versionInfo c =
|
||||||
html200 . unlines $
|
html200 . unlines $
|
||||||
"<!DOCTYPE html>":
|
"<!DOCTYPE html>":
|
||||||
"<meta name = \"viewport\" content = \"width = device-width\">":
|
"<meta name = \"viewport\" content = \"width = device-width\">":
|
||||||
@@ -187,8 +187,7 @@ handle logLn documentroot state0 cache execute1 stateVar
|
|||||||
"":
|
"":
|
||||||
("<h2>"++hdr++"</h2>"):
|
("<h2>"++hdr++"</h2>"):
|
||||||
(zipWith (++) ("<p>":repeat "<br>") buildinfo)++
|
(zipWith (++) ("<p>":repeat "<br>") buildinfo)++
|
||||||
sh "Haskell run-time system" c1++
|
sh "Run-time system" c
|
||||||
sh "C run-time system" c2
|
|
||||||
where
|
where
|
||||||
hdr:buildinfo = lines gf_version
|
hdr:buildinfo = lines gf_version
|
||||||
rel = makeRelative documentroot
|
rel = makeRelative documentroot
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ module PGFService(cgiMain,cgiMain',getPath,
|
|||||||
Caches,pgfCache,newPGFCache,flushPGFCache,listPGFCache) where
|
Caches,pgfCache,newPGFCache,flushPGFCache,listPGFCache) where
|
||||||
|
|
||||||
import PGF (PGF,Labels,CncLabels)
|
import PGF (PGF,Labels,CncLabels)
|
||||||
|
import PGF2
|
||||||
import GF.Text.Lexing
|
import GF.Text.Lexing
|
||||||
import qualified PGF
|
import qualified PGF
|
||||||
import Cache
|
import Cache
|
||||||
@@ -15,11 +16,6 @@ import CGI(CGI,readInput,getInput,getVarWithDefault,
|
|||||||
Accept(..),Language(..),negotiate,liftIO)
|
Accept(..),Language(..),negotiate,liftIO)
|
||||||
import URLEncoding
|
import URLEncoding
|
||||||
|
|
||||||
#if C_RUNTIME
|
|
||||||
import qualified PGF2 as C
|
|
||||||
--import Data.Time.Clock(getCurrentTime,diffUTCTime)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
import Data.Time.Clock(UTCTime)
|
import Data.Time.Clock(UTCTime)
|
||||||
import Data.Time.Format(formatTime)
|
import Data.Time.Format(formatTime)
|
||||||
#if MIN_VERSION_time(1,5,0)
|
#if MIN_VERSION_time(1,5,0)
|
||||||
@@ -60,43 +56,18 @@ withQSem qsem = bracket_ (liftIO $ waitQSem qsem) (liftIO $ signalQSem qsem)
|
|||||||
logFile :: FilePath
|
logFile :: FilePath
|
||||||
logFile = "pgf-error.log"
|
logFile = "pgf-error.log"
|
||||||
|
|
||||||
#ifdef C_RUNTIME
|
data Caches = Caches { qsem :: QSem,
|
||||||
data Caches = Caches { pgfCache::Cache PGF,
|
pgfCache :: Cache PGF,
|
||||||
labelsCache::Cache Labels,
|
labelsCache :: Cache Labels }
|
||||||
cncLabelsCache::Cache CncLabels,
|
|
||||||
cpgfCache::(Cache (C.PGF,({-MVar ParseCache-})),QSem) }
|
|
||||||
--type Caches = (Cache PGF,Cache (C.PGF,({-MVar ParseCache-})))
|
|
||||||
--type ParseCache = Map.Map (String,String) (ParseResult,UTCTime)
|
|
||||||
--type ParseResult = Either String [(C.Expr,Float)]
|
|
||||||
|
|
||||||
newPGFCache jobs = do pgfCache <- newCache' PGF.readPGF
|
newPGFCache jobs = do let n = maybe 4 id jobs
|
||||||
lblCache <- newCache' (fmap PGF.getDepLabels . readFile)
|
|
||||||
clblCache <- newCache'(fmap PGF.getCncDepLabels .readFile)
|
|
||||||
let n = maybe 4 id jobs
|
|
||||||
qsem <- newQSem n
|
qsem <- newQSem n
|
||||||
cCache <- newCache' $ \ path -> do pgf <- C.readPGF path
|
pgfCache <- newCache' PGF.readPGF
|
||||||
--pc <- newMVar Map.empty
|
lblCache <- newCache' (fmap PGF.getDepLabels . readFile)
|
||||||
return (pgf,({-pc-}))
|
return $ Caches qsem pgfCache lblCache
|
||||||
return $ Caches pgfCache lblCache clblCache (cCache,qsem)
|
|
||||||
flushPGFCache c = do flushCache (pgfCache c)
|
flushPGFCache c = do flushCache (pgfCache c)
|
||||||
flushCache (labelsCache c)
|
flushCache (labelsCache c)
|
||||||
flushCache (fst (cpgfCache c))
|
listPGFCache c = listCache (pgfCache c)
|
||||||
listPGFCache c = (,) # listCache (pgfCache c) % listCache (fst (cpgfCache c))
|
|
||||||
#else
|
|
||||||
data Caches = Caches { pgfCache::Cache PGF,
|
|
||||||
labelsCache::Cache Labels,
|
|
||||||
cncLabelsCache::Cache CncLabels }
|
|
||||||
newPGFCache _ = do pgfCache <- newCache' PGF.readPGF
|
|
||||||
lblCache <- newCache' (fmap PGF.getDepLabels . readFile)
|
|
||||||
clblCache <- newCache'(fmap PGF.getCncDepLabels .readFile)
|
|
||||||
return $ Caches pgfCache lblCache clblCache
|
|
||||||
flushPGFCache c = flushCache (pgfCache c)
|
|
||||||
|
|
||||||
listPGFCache :: Caches -> IO ([(FilePath,UTCTime)],[(FilePath,UTCTime)])
|
|
||||||
listPGFCache c = (,) # listCache (pgfCache c) % return []
|
|
||||||
#endif
|
|
||||||
|
|
||||||
labelsCaches c = (labelsCache c,cncLabelsCache c)
|
|
||||||
|
|
||||||
newCache' rd = do c <- newCache rd
|
newCache' rd = do c <- newCache rd
|
||||||
forkIO $ forever $ clean c
|
forkIO $ forever $ clean c
|
||||||
@@ -121,20 +92,8 @@ cgiMain' cache path =
|
|||||||
(getInput "command")
|
(getInput "command")
|
||||||
case command of
|
case command of
|
||||||
"download" -> outputBinary =<< getFile BS.readFile path
|
"download" -> outputBinary =<< getFile BS.readFile path
|
||||||
'c':'-':_ -> optionalCpgfMain cache path command
|
|
||||||
_ -> do tpgf <- getFile (readCache' (pgfCache cache)) path
|
_ -> do tpgf <- getFile (readCache' (pgfCache cache)) path
|
||||||
pgfMain (labelsCaches cache) path command tpgf
|
pgfMain (qsem cache) command tpgf
|
||||||
|
|
||||||
optionalCpgfMain cache path command =
|
|
||||||
#ifdef C_RUNTIME
|
|
||||||
cpgfMain (snd (cpgfCache cache)) command
|
|
||||||
=<< getFile (readCache' (fst (cpgfCache cache))) path
|
|
||||||
#else
|
|
||||||
serverError "Server configured without C run-time support" ""
|
|
||||||
|
|
||||||
serverError = throw 500
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
getFile get path =
|
getFile get path =
|
||||||
either failed return =<< liftIO (E.try (get path))
|
either failed return =<< liftIO (E.try (get path))
|
||||||
@@ -143,38 +102,34 @@ getFile get path =
|
|||||||
then notFound path
|
then notFound path
|
||||||
else liftIO $ ioError e
|
else liftIO $ ioError e
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
-- * C run-time functionality
|
|
||||||
|
|
||||||
#ifdef C_RUNTIME
|
pgfMain qsem command (t,pgf) =
|
||||||
--cpgfMain :: String -> (C.PGF,MVar ParseCache) -> CGI CGIResult
|
|
||||||
cpgfMain qsem command (t,(pgf,pc)) =
|
|
||||||
case command of
|
case command of
|
||||||
"c-parse" -> withQSem qsem $
|
"parse" -> withQSem qsem $
|
||||||
out t=<< join (parse # input % start % limit % treeopts)
|
out t=<< join (parse # input % start % limit % treeopts)
|
||||||
"c-linearize" -> out t=<< lin # tree % to
|
"linearize" -> out t=<< lin # tree % to
|
||||||
"c-linearizeAll"-> out t=<< linAll # tree % to
|
"linearizeAll"-> out t=<< linAll # tree % to
|
||||||
"c-translate" -> withQSem qsem $
|
"translate" -> withQSem qsem $
|
||||||
out t=<<join(trans # input % to % start % limit%treeopts)
|
out t=<<join(trans # input % to % start % limit%treeopts)
|
||||||
"c-lookupmorpho"-> out t=<< morpho # from1 % textInput
|
"lookupmorpho"-> out t=<< morpho # from1 % textInput
|
||||||
"c-flush" -> out t=<< flush
|
"flush" -> out t=<< flush
|
||||||
"c-grammar" -> out t grammar
|
"grammar" -> out t grammar
|
||||||
"c-abstrtree" -> outputGraphviz=<< C.graphvizAbstractTree pgf C.graphvizDefaults # tree
|
"abstrtree" -> outputGraphviz=<< graphvizAbstractTree pgf graphvizDefaults # tree
|
||||||
"c-parsetree" -> outputGraphviz=<< (\cnc -> C.graphvizParseTree cnc C.graphvizDefaults) . snd # from1 %tree
|
"parsetree" -> outputGraphviz=<< (\cnc -> graphvizParseTree cnc graphvizDefaults) . snd # from1 %tree
|
||||||
"c-wordforword" -> out t =<< wordforword # input % to
|
"wordforword" -> out t =<< wordforword # input % to
|
||||||
_ -> badRequest "Unknown command" command
|
_ -> badRequest "Unknown command" command
|
||||||
where
|
where
|
||||||
flush = liftIO $ do --modifyMVar_ pc $ const $ return Map.empty
|
flush = liftIO $ do --modifyMVar_ pc $ const $ return Map.empty
|
||||||
performGC
|
performGC
|
||||||
return $ showJSON ()
|
return $ showJSON ()
|
||||||
|
|
||||||
cat = C.startCat pgf
|
cat = startCat pgf
|
||||||
langs = C.languages pgf
|
langs = languages pgf
|
||||||
|
|
||||||
grammar = showJSON $ makeObj
|
grammar = showJSON $ makeObj
|
||||||
["name".=C.abstractName pgf,
|
["name".=abstractName pgf,
|
||||||
"lastmodified".=show t,
|
"lastmodified".=show t,
|
||||||
"startcat".=C.showType [] (C.startCat pgf),
|
"startcat".=showType [] (startCat pgf),
|
||||||
"languages".=languages]
|
"languages".=languages]
|
||||||
where
|
where
|
||||||
languages = [makeObj ["name".= l] | (l,_)<-Map.toList langs]
|
languages = [makeObj ["name".= l] | (l,_)<-Map.toList langs]
|
||||||
@@ -189,40 +144,23 @@ cpgfMain qsem command (t,(pgf,pc)) =
|
|||||||
good trees = "trees".=map tp trees :[] -- :addTrie trie trees
|
good trees = "trees".=map tp trees :[] -- :addTrie trie trees
|
||||||
tp (tree,prob) = makeObj (addTree json tree++["prob".=prob])
|
tp (tree,prob) = makeObj (addTree json tree++["prob".=prob])
|
||||||
|
|
||||||
-- Without caching parse results:
|
|
||||||
parse' start mlimit ((from,concr),input) =
|
parse' start mlimit ((from,concr),input) =
|
||||||
case C.parseWithHeuristics concr cat input (-1) callbacks of
|
case parseWithHeuristics concr cat input (-1) callbacks of
|
||||||
C.ParseOk ts -> return (Right (maybe id take mlimit (drop start ts)))
|
ParseOk ts -> return (Right (maybe id take mlimit (drop start ts)))
|
||||||
C.ParseFailed _ tok -> return (Left tok)
|
ParseFailed _ tok -> return (Left tok)
|
||||||
C.ParseIncomplete -> return (Left "")
|
ParseIncomplete -> return (Left "")
|
||||||
where
|
where
|
||||||
callbacks = maybe [] cb $ lookup (C.abstractName pgf) C.literalCallbacks
|
callbacks = maybe [] cb $ lookup (abstractName pgf) literalCallbacks
|
||||||
cb fs = [(cat,f pgf (from,concr) input)|(cat,f)<-fs]
|
cb fs = [(cat,f pgf (from,concr) input)|(cat,f)<-fs]
|
||||||
{-
|
|
||||||
-- Caching parse results:
|
|
||||||
parse' start mlimit ((from,concr),input) =
|
|
||||||
liftIO $ do t <- getCurrentTime
|
|
||||||
fmap (maybe id take mlimit . drop start)
|
|
||||||
# modifyMVar pc (parse'' t)
|
|
||||||
where
|
|
||||||
key = (from,input)
|
|
||||||
parse'' t pc = maybe new old $ Map.lookup key pc
|
|
||||||
where
|
|
||||||
new = return (update (res,t) pc,res)
|
|
||||||
where res = C.parse concr cat input
|
|
||||||
old (res,_) = return (update (res,t) pc,res)
|
|
||||||
update r = Map.mapMaybe purge . Map.insert key r
|
|
||||||
purge r@(_,t') = if diffUTCTime t t'<120 then Just r else Nothing
|
|
||||||
-- remove unused parse results after 2 minutes
|
|
||||||
-}
|
|
||||||
linAll tree to = showJSON (linAll' tree to)
|
linAll tree to = showJSON (linAll' tree to)
|
||||||
linAll' tree (tos,unlex) =
|
linAll' tree (tos,unlex) =
|
||||||
[makeObj ["to".=to,
|
[makeObj ["to".=to,
|
||||||
"texts".=map unlex (C.linearizeAll c tree)]|(to,c)<-tos]
|
"texts".=map unlex (linearizeAll c tree)]|(to,c)<-tos]
|
||||||
|
|
||||||
lin tree to = showJSON (lin' tree to)
|
lin tree to = showJSON (lin' tree to)
|
||||||
lin' tree (tos,unlex) =
|
lin' tree (tos,unlex) =
|
||||||
[makeObj ["to".=to,"text".=unlex (C.linearize c tree)]|(to,c)<-tos]
|
[makeObj ["to".=to,"text".=unlex (linearize c tree)]|(to,c)<-tos]
|
||||||
|
|
||||||
trans input@((from,_),_) to start mlimit (trie,jsontree) =
|
trans input@((from,_),_) to start mlimit (trie,jsontree) =
|
||||||
do parses <- parse' start mlimit input
|
do parses <- parse' start mlimit input
|
||||||
@@ -240,7 +178,7 @@ cpgfMain qsem command (t,(pgf,pc)) =
|
|||||||
|
|
||||||
morpho (from,concr) input =
|
morpho (from,concr) input =
|
||||||
showJSON [makeObj ["lemma".=l,"analysis".=a,"prob".=p]|(l,a,p)<-ms]
|
showJSON [makeObj ["lemma".=l,"analysis".=a,"prob".=p]|(l,a,p)<-ms]
|
||||||
where ms = C.lookupMorpho concr input
|
where ms = lookupMorpho concr input
|
||||||
|
|
||||||
|
|
||||||
wordforword input@((from,_),_) = jsonWFW from . wordforword' input
|
wordforword input@((from,_),_) = jsonWFW from . wordforword' input
|
||||||
@@ -259,7 +197,7 @@ cpgfMain qsem command (t,(pgf,pc)) =
|
|||||||
where
|
where
|
||||||
lin_word' c = either id (lin1 c)
|
lin_word' c = either id (lin1 c)
|
||||||
|
|
||||||
lin1 c = dropq . C.linearize c
|
lin1 c = dropq . linearize c
|
||||||
where
|
where
|
||||||
dropq (q:' ':s) | q `elem` "+*" = s
|
dropq (q:' ':s) | q `elem` "+*" = s
|
||||||
dropq s = s
|
dropq s = s
|
||||||
@@ -278,12 +216,12 @@ cpgfMain qsem command (t,(pgf,pc)) =
|
|||||||
| isUpper c -> toLower c : cs
|
| isUpper c -> toLower c : cs
|
||||||
s -> s
|
s -> s
|
||||||
|
|
||||||
parse1 s = case C.parse concr cat s of
|
parse1 s = case PGF2.parse concr cat s of
|
||||||
C.ParseOk ((t,_):ts) -> Just t
|
ParseOk ((t,_):ts) -> Just t
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
morph w = listToMaybe
|
morph w = listToMaybe
|
||||||
[t | (f,a,p)<-C.lookupMorpho concr w,
|
[t | (f,a,p)<-lookupMorpho concr w,
|
||||||
t<-maybeToList (C.readExpr f)]
|
t<-maybeToList (readExpr f)]
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -303,28 +241,17 @@ cpgfMain qsem command (t,(pgf,pc)) =
|
|||||||
getLangs = getLangs' readLang
|
getLangs = getLangs' readLang
|
||||||
getLang = getLang' readLang
|
getLang = getLang' readLang
|
||||||
|
|
||||||
readLang :: String -> CGI (String,C.Concr)
|
readLang :: String -> CGI (String,Concr)
|
||||||
readLang lang =
|
readLang lang =
|
||||||
case Map.lookup lang langs of
|
case Map.lookup lang langs of
|
||||||
Nothing -> badRequest "Bad language" lang
|
Nothing -> badRequest "Bad language" lang
|
||||||
Just c -> return (lang,c)
|
Just c -> return (lang,c)
|
||||||
|
|
||||||
tree = do s <- maybe (missing "tree") return =<< getInput1 "tree"
|
tree = do s <- maybe (missing "tree") return =<< getInput1 "tree"
|
||||||
let t = C.readExpr s
|
maybe (badRequest "bad tree" s) return (readExpr s)
|
||||||
maybe (badRequest "bad tree" s) return t
|
|
||||||
|
|
||||||
c_lexer concr = lexer (not . null . C.lookupMorpho concr)
|
c_lexer concr = lexer (not . null . lookupMorpho concr)
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
-- | Convert a 'Tree' to an 'ATree'
|
|
||||||
cToATree :: C.Expr -> PGF.ATree C.Expr
|
|
||||||
cToATree e = maybe (PGF.Other e) app (C.unApp e)
|
|
||||||
where
|
|
||||||
app (f,es) = PGF.App (read f) (map cToATree es)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- * Lexing
|
-- * Lexing
|
||||||
@@ -355,7 +282,7 @@ unlexer good = maybe (return id) unlexerfun =<< getInput "unlexer"
|
|||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- * Haskell run-time functionality
|
-- * Haskell run-time functionality
|
||||||
|
{-
|
||||||
--pgfMain :: Cache Labels -> FilePath -> String -> PGF -> CGI CGIResult
|
--pgfMain :: Cache Labels -> FilePath -> String -> PGF -> CGI CGIResult
|
||||||
pgfMain lcs@(alc,clc) path command tpgf@(t,pgf) =
|
pgfMain lcs@(alc,clc) path command tpgf@(t,pgf) =
|
||||||
case command of
|
case command of
|
||||||
@@ -464,7 +391,7 @@ pgfMain lcs@(alc,clc) path command tpgf@(t,pgf) =
|
|||||||
|
|
||||||
-- * Request parameter access and related auxiliary functions
|
-- * Request parameter access and related auxiliary functions
|
||||||
|
|
||||||
--out = outputJSONP
|
-}
|
||||||
out t r = do let fmt = formatTime defaultTimeLocale rfc822DateFormat t
|
out t r = do let fmt = formatTime defaultTimeLocale rfc822DateFormat t
|
||||||
setHeader "Last-Modified" fmt
|
setHeader "Last-Modified" fmt
|
||||||
outputJSONP r
|
outputJSONP r
|
||||||
@@ -508,7 +435,7 @@ throw code msg extra =
|
|||||||
throwCGIError code msg [msg ++(if null extra then "" else ": "++extra)]
|
throwCGIError code msg [msg ++(if null extra then "" else ": "++extra)]
|
||||||
|
|
||||||
format def = maybe def id # getInput "format"
|
format def = maybe def id # getInput "format"
|
||||||
|
{-
|
||||||
-- * Request implementations
|
-- * Request implementations
|
||||||
|
|
||||||
-- Hook for simple extensions of the PGF service
|
-- Hook for simple extensions of the PGF service
|
||||||
@@ -537,11 +464,11 @@ doLookupMorpho pgf from input =
|
|||||||
where
|
where
|
||||||
ms = PGF.lookupMorpho (PGF.buildMorpho pgf from) input
|
ms = PGF.lookupMorpho (PGF.buildMorpho pgf from) input
|
||||||
|
|
||||||
|
-}
|
||||||
type From = (Maybe PGF.Language,String)
|
type From = (Maybe PGF.Language,String)
|
||||||
type To = ([PGF.Language],Unlexer)
|
type To = ([PGF.Language],Unlexer)
|
||||||
type TreeOpts = (Bool,Bool) -- (trie,jsontree)
|
type TreeOpts = (Bool,Bool) -- (trie,jsontree)
|
||||||
|
{-
|
||||||
doTranslate :: PGF -> From -> Maybe PGF.Type -> To -> Maybe Int -> TreeOpts -> JSValue
|
doTranslate :: PGF -> From -> Maybe PGF.Type -> To -> Maybe Int -> TreeOpts -> JSValue
|
||||||
doTranslate pgf (mfrom,input) mcat tos mlimit (trie,jsontree) =
|
doTranslate pgf (mfrom,input) mcat tos mlimit (trie,jsontree) =
|
||||||
showJSON
|
showJSON
|
||||||
@@ -633,10 +560,10 @@ doParse pgf (mfrom,input) mcat mlimit (trie,jsontree) = showJSON $ map makeObj
|
|||||||
|
|
||||||
addTrie trie trees =
|
addTrie trie trees =
|
||||||
["trie".=map head (PGF.toTrie (map PGF.toATree trees))|trie]
|
["trie".=map head (PGF.toTrie (map PGF.toATree trees))|trie]
|
||||||
|
-}
|
||||||
addTree json tree = "tree".=showTree tree:
|
addTree json tree = "tree".=showTree tree:
|
||||||
["jsontree".= jsonExpr tree | json]
|
["jsontree".= jsonExpr tree | json]
|
||||||
|
{-
|
||||||
doComplete :: PGF -> From -> Maybe PGF.Type -> Maybe Int -> Bool -> JSValue
|
doComplete :: PGF -> From -> Maybe PGF.Type -> Maybe Int -> Bool -> JSValue
|
||||||
doComplete pgf (mfrom,input) mcat mlimit full = showJSON
|
doComplete pgf (mfrom,input) mcat mlimit full = showJSON
|
||||||
[makeObj (
|
[makeObj (
|
||||||
@@ -732,7 +659,7 @@ doGrammar (t1,pgf) elbls macc = out t $ showJSON $ makeObj
|
|||||||
| l <- PGF.languages pgf]
|
| l <- PGF.languages pgf]
|
||||||
categories = [PGF.showCId cat | cat <- PGF.categories pgf]
|
categories = [PGF.showCId cat | cat <- PGF.categories pgf]
|
||||||
functions = [PGF.showCId fun | fun <- PGF.functions pgf]
|
functions = [PGF.showCId fun | fun <- PGF.functions pgf]
|
||||||
|
-}
|
||||||
outputGraphviz code =
|
outputGraphviz code =
|
||||||
do fmt <- format "png"
|
do fmt <- format "png"
|
||||||
case fmt of
|
case fmt of
|
||||||
@@ -748,7 +675,7 @@ outputGraphviz code =
|
|||||||
"svg" -> "image/svg+xml"
|
"svg" -> "image/svg+xml"
|
||||||
-- ...
|
-- ...
|
||||||
_ -> "application/binary"
|
_ -> "application/binary"
|
||||||
|
{-
|
||||||
abstrTree pgf opts tree = PGF.graphvizAbstractTree pgf opts' tree
|
abstrTree pgf opts tree = PGF.graphvizAbstractTree pgf opts' tree
|
||||||
where opts' = (not (PGF.noFun opts),not (PGF.noCat opts))
|
where opts' = (not (PGF.noFun opts),not (PGF.noCat opts))
|
||||||
|
|
||||||
@@ -789,7 +716,7 @@ tryIO = E.try
|
|||||||
|
|
||||||
alignment pgf tree (tos,unlex) = PGF.graphvizAlignment pgf tos' tree
|
alignment pgf tree (tos,unlex) = PGF.graphvizAlignment pgf tos' tree
|
||||||
where tos' = if null tos then PGF.languages pgf else tos
|
where tos' = if null tos then PGF.languages pgf else tos
|
||||||
|
-}
|
||||||
pipeIt2graphviz :: String -> String -> IO BS.ByteString
|
pipeIt2graphviz :: String -> String -> IO BS.ByteString
|
||||||
pipeIt2graphviz fmt code = do
|
pipeIt2graphviz fmt code = do
|
||||||
(Just inh, Just outh, _, pid) <-
|
(Just inh, Just outh, _, pid) <-
|
||||||
@@ -821,7 +748,7 @@ pipeIt2graphviz fmt code = do
|
|||||||
case ex of
|
case ex of
|
||||||
ExitSuccess -> return output
|
ExitSuccess -> return output
|
||||||
ExitFailure r -> fail ("pipeIt2graphviz: (exit " ++ show r ++ ")")
|
ExitFailure r -> fail ("pipeIt2graphviz: (exit " ++ show r ++ ")")
|
||||||
|
{-
|
||||||
browse1json pgf id pn = makeObj . maybe [] obj $ PGF.browse pgf id
|
browse1json pgf id pn = makeObj . maybe [] obj $ PGF.browse pgf id
|
||||||
where
|
where
|
||||||
obj (def,ps,cs) = if pn then (baseobj ++ pnames) else baseobj
|
obj (def,ps,cs) = if pn then (baseobj ++ pnames) else baseobj
|
||||||
@@ -921,7 +848,7 @@ doBrowse pgf (Just id) cssClass href _ pn = -- default to "html" format
|
|||||||
|
|
||||||
annotatePrintNames = "<DL>"++(unwords pns)++"</DL>"
|
annotatePrintNames = "<DL>"++(unwords pns)++"</DL>"
|
||||||
where pns = ["<DT>"++(show lang)++"</DT><DD>"++(PGF.showPrintName pgf lang id)++"</DD>" | lang <- PGF.languages pgf ]
|
where pns = ["<DT>"++(show lang)++"</DT><DD>"++(PGF.showPrintName pgf lang id)++"</DD>" | lang <- PGF.languages pgf ]
|
||||||
|
-}
|
||||||
class ToATree a where
|
class ToATree a where
|
||||||
showTree :: a -> String
|
showTree :: a -> String
|
||||||
toATree :: a -> PGF.ATree a
|
toATree :: a -> PGF.ATree a
|
||||||
@@ -961,11 +888,7 @@ instance JSON PGF.Expr where
|
|||||||
|
|
||||||
instance JSON PGF.BracketedString where
|
instance JSON PGF.BracketedString where
|
||||||
readJSON x = return (PGF.Leaf "")
|
readJSON x = return (PGF.Leaf "")
|
||||||
#ifdef C_RUNTIME
|
|
||||||
showJSON (PGF.Bracket cat fid index fun bs) =
|
showJSON (PGF.Bracket cat fid index fun bs) =
|
||||||
#else
|
|
||||||
showJSON (PGF.Bracket cat fid index fun _ bs) =
|
|
||||||
#endif
|
|
||||||
makeObj ["cat".=cat, "fid".=fid, "index".=index, "fun".=fun, "children".=bs]
|
makeObj ["cat".=cat, "fid".=fid, "index".=index, "fun".=fun, "children".=bs]
|
||||||
showJSON (PGF.Leaf s) = makeObj ["token".=s]
|
showJSON (PGF.Leaf s) = makeObj ["token".=s]
|
||||||
|
|
||||||
@@ -1038,3 +961,4 @@ f % x = ap f x
|
|||||||
|
|
||||||
--cleanFilePath :: FilePath -> FilePath
|
--cleanFilePath :: FilePath -> FilePath
|
||||||
--cleanFilePath = takeFileName
|
--cleanFilePath = takeFileName
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user