diff options
| author | hallgren <hallgren@chalmers.se> | 2013-11-11 15:13:24 +0000 |
|---|---|---|
| committer | hallgren <hallgren@chalmers.se> | 2013-11-11 15:13:24 +0000 |
| commit | 47e04656fb11c39ec9cbbfd7c860cd992d4855d2 (patch) | |
| tree | c1f4fc0af038a12ff495350183dbd4843fd8d885 /src | |
| parent | af4a1f628d2e35503402fc24ae0f6cc0c274788e (diff) | |
Fix issue 61: GF shell cannot parse a system command ending with a space
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".
Diffstat (limited to 'src')
| -rw-r--r-- | src/compiler/GF/Command/Parse.hs | 78 |
1 files changed, 40 insertions, 38 deletions
diff --git a/src/compiler/GF/Command/Parse.hs b/src/compiler/GF/Command/Parse.hs index 855fdb54e..0967f30e9 100644 --- a/src/compiler/GF/Command/Parse.hs +++ b/src/compiler/GF/Command/Parse.hs @@ -1,63 +1,65 @@ module GF.Command.Parse(readCommandLine, pCommand) where -import PGF +import PGF(pExpr,pIdent) import GF.Command.Abstract -import Data.Char -import Control.Monad -import qualified Text.ParserCombinators.ReadP as RP +import Data.Char(isDigit,isSpace) +import Control.Monad(liftM2) +import Text.ParserCombinators.ReadP readCommandLine :: String -> Maybe CommandLine -readCommandLine s = case [x | (x,cs) <- RP.readP_to_S pCommandLine s, all isSpace cs] of - [x] -> Just x - _ -> Nothing +readCommandLine s = + case [x | (x,cs) <- readP_to_S pCommandLine s, all isSpace cs] of + [x] -> Just x + _ -> Nothing pCommandLine = - (RP.skipSpaces >> RP.char '-' >> RP.char '-' >> RP.skipMany (RP.satisfy (const True)) >> return []) -- comment - RP.<++ - (RP.sepBy (RP.skipSpaces >> pPipe) (RP.skipSpaces >> RP.char ';')) + (skipSpaces >> char '-' >> char '-' >> pTheRest >> return []) -- comment + <++ + (sepBy (skipSpaces >> pPipe) (skipSpaces >> char ';')) -pPipe = RP.sepBy1 (RP.skipSpaces >> pCommand) (RP.skipSpaces >> RP.char '|') +pPipe = sepBy1 (skipSpaces >> pCommand) (skipSpaces >> char '|') pCommand = (do - cmd <- pIdent RP.<++ (RP.char '%' >> pIdent >>= return . ('%':)) - RP.skipSpaces - opts <- RP.sepBy pOption RP.skipSpaces + cmd <- pIdent <++ (char '%' >> pIdent >>= return . ('%':)) + skipSpaces + opts <- sepBy pOption skipSpaces arg <- pArgument return (Command cmd opts arg) ) - RP.<++ (do - RP.char '?' - c <- pSystemCommand + <++ (do + char '?' + skipSpaces + c <- pSystemCommand return (Command "sp" [OFlag "command" (VStr c)] ANoArg) - ) + ) pOption = do - RP.char '-' + char '-' flg <- pIdent - RP.option (OOpt flg) (fmap (OFlag flg) (RP.char '=' >> pValue)) + option (OOpt flg) (fmap (OFlag flg) (char '=' >> pValue)) pValue = do - fmap VInt (RP.readS_to_P reads) - RP.<++ - fmap VStr (RP.readS_to_P reads) - RP.<++ + fmap VInt (readS_to_P reads) + <++ + fmap VStr (readS_to_P reads) + <++ fmap VId pFilename -pFilename = liftM2 (:) (RP.satisfy isFileFirst) (RP.munch (not . isSpace)) where +pFilename = liftM2 (:) (satisfy isFileFirst) (munch (not . isSpace)) where isFileFirst c = not (isSpace c) && not (isDigit c) -pArgument = - RP.option ANoArg +pArgument = + option ANoArg (fmap AExpr pExpr - RP.<++ - (RP.munch isSpace >> RP.char '%' >> fmap AMacro pIdent)) - -pSystemCommand = - RP.munch isSpace >> ( - (RP.char '"' >> (RP.manyTill (pEsc RP.<++ RP.get) (RP.char '"'))) - RP.<++ - RP.many RP.get - ) - where - pEsc = RP.char '\\' >> RP.get + <++ + (skipSpaces >> char '%' >> fmap AMacro pIdent)) + +pSystemCommand = + (char '"' >> (manyTill (pEsc <++ get) (char '"'))) + <++ + pTheRest + where + pEsc = char '\\' >> get + +pTheRest = munch (const True) |
