forked from GitHub/gf-core
Trailing spaces caused the command line parse to be ambiguous, and ambiguous parses were rejected by function readCommandLine, causing the cryptic error message "command not parsed".
66 lines
1.5 KiB
Haskell
66 lines
1.5 KiB
Haskell
module GF.Command.Parse(readCommandLine, pCommand) where
|
|
|
|
import PGF(pExpr,pIdent)
|
|
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 <- pIdent <++ (char '%' >> pIdent >>= return . ('%':))
|
|
skipSpaces
|
|
opts <- sepBy pOption skipSpaces
|
|
arg <- pArgument
|
|
return (Command cmd opts arg)
|
|
)
|
|
<++ (do
|
|
char '?'
|
|
skipSpaces
|
|
c <- pSystemCommand
|
|
return (Command "sp" [OFlag "command" (VStr c)] ANoArg)
|
|
)
|
|
|
|
pOption = do
|
|
char '-'
|
|
flg <- 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 pExpr
|
|
<++
|
|
(skipSpaces >> char '%' >> fmap AMacro pIdent))
|
|
|
|
pSystemCommand =
|
|
(char '"' >> (manyTill (pEsc <++ get) (char '"')))
|
|
<++
|
|
pTheRest
|
|
where
|
|
pEsc = char '\\' >> get
|
|
|
|
pTheRest = munch (const True)
|