mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-09 04:59:31 -06:00
73 lines
1.8 KiB
Haskell
73 lines
1.8 KiB
Haskell
module GF.Command.Parse(readCommandLine, pCommand) where
|
|
|
|
import PGF2(pExpr,pIdent)
|
|
import GF.Grammar.Parser(runPartial,pTerm)
|
|
import GF.Command.Abstract
|
|
|
|
import Data.Char(isDigit,isSpace)
|
|
import Control.Monad(liftM2)
|
|
import Text.ParserCombinators.ReadP
|
|
|
|
readCommandLine :: String -> Maybe CommandLine
|
|
readCommandLine s =
|
|
case [x | (x,cs) <- readP_to_S pCommandLine s, all isSpace cs] of
|
|
[x] -> Just x
|
|
_ -> Nothing
|
|
|
|
pCommandLine =
|
|
(skipSpaces >> char '-' >> char '-' >> pTheRest >> return []) -- comment
|
|
<++
|
|
(sepBy (skipSpaces >> pPipe) (skipSpaces >> char ';'))
|
|
|
|
pPipe = sepBy1 (skipSpaces >> pCommand) (skipSpaces >> char '|')
|
|
|
|
pCommand = (do
|
|
cmd <- readS_to_P pIdent <++ (char '%' >> fmap ('%':) (readS_to_P pIdent))
|
|
skipSpaces
|
|
opts <- sepBy pOption skipSpaces
|
|
arg <- if getCommandOp cmd == "cc" then pArgTerm else pArgument
|
|
return (Command cmd opts arg)
|
|
)
|
|
<++ (do
|
|
char '?'
|
|
skipSpaces
|
|
c <- pSystemCommand
|
|
return (Command "sp" [OFlag "command" (VStr c)] ANoArg)
|
|
)
|
|
|
|
pOption = do
|
|
char '-'
|
|
flg <- readS_to_P pIdent
|
|
option (OOpt flg) (fmap (OFlag flg) (char '=' >> pValue))
|
|
|
|
pValue = do
|
|
fmap VInt (readS_to_P reads)
|
|
<++
|
|
fmap VStr (readS_to_P reads)
|
|
<++
|
|
fmap VId pFilename
|
|
|
|
pFilename = liftM2 (:) (satisfy isFileFirst) (munch (not . isSpace)) where
|
|
isFileFirst c = not (isSpace c) && not (isDigit c)
|
|
|
|
pArgument =
|
|
option ANoArg
|
|
(fmap AExpr (readS_to_P pExpr)
|
|
<++
|
|
(skipSpaces >> char '%' >> fmap AMacro (readS_to_P pIdent)))
|
|
|
|
pArgTerm = ATerm `fmap` readS_to_P sTerm
|
|
where
|
|
sTerm s = case runPartial pTerm s of
|
|
Right (s,t) -> [(t,s)]
|
|
_ -> []
|
|
|
|
pSystemCommand =
|
|
(char '"' >> (manyTill (pEsc <++ get) (char '"')))
|
|
<++
|
|
pTheRest
|
|
where
|
|
pEsc = char '\\' >> get
|
|
|
|
pTheRest = munch (const True)
|