fst-0.10.0.0: FST/Arguments.hs
{- |
Helper functions for handling shell/command-line options
-}
module FST.Arguments (
-- * Commands ADT
InteractiveCommand (..),
BatchCommand (..),
-- * Helper functions
parseInteractive,
isFST,
isDAT,
isNET,
isTHIS,
parseBatch,
inputB,
outputB,
isUpB
) where
import System.Console.GetOpt
import Data.List
import Data.Maybe
-- | ADT for a shell command
data InteractiveCommand =
-- | Build an epsilon-free, deterministic, minimal transducer from a
-- loaded/typed regular relation.
BuildTransducer
-- | Build an epsilon-free, possibly non-deterministic, non-minimal
-- transducer from a load/typed regular relation.
| BuildNTransducer
-- | Minimize a built transducer.
| Minimize
-- | Determinize a built transducer.
| Determinize
-- | Read a regular relation from standard input.
| StdInReg String
-- | Load from FILE.
| Load FilePath
-- | Load and union two transducers.
| LUnion FilePath FilePath
-- | Load and concatenate two transducers.
| LProduct FilePath FilePath
-- | Load and apply Kleene's star on a transducer.
| LStar FilePath
-- | Load and compose two transducers.
| LComposition FilePath FilePath
-- | Save to file.
| Save FilePath
-- | Apply transducer down with loaded input.
| ApplyDown
-- | Apply transducer up with loaded input.
| ApplyUp
-- | Apply tranducer down with given symbols.
| ApplyD [String]
-- | Apply tranducer up with given symbols.
| ApplyU [String]
-- | View loaded/typed regular relation.
| ViewReg
-- | View loaded input.
| ViewInput
-- | View prodeced output.
| ViewOutput
-- | View loaded/built transducer.
| ViewTransducer
-- | List commands.
| Help
-- | Clear loaded transducers/input/output.
| ClearMemory
-- | Quit the shell
| Quit
-- | Unparseable command
| NoCommand
deriving (Eq, Show)
-- | Parse input string into a command
parseInteractive :: [String] -> InteractiveCommand
parseInteractive ["b"] = BuildTransducer
parseInteractive ["bn"] = BuildNTransducer
parseInteractive ["m"] = Minimize
parseInteractive ["det"] = Determinize
parseInteractive ("r":xs) = StdInReg (unwords xs)
parseInteractive ["d"] = ApplyDown
parseInteractive ["u"] = ApplyUp
parseInteractive ("d":xs) = ApplyD xs
parseInteractive ("u":xs) = ApplyU xs
parseInteractive ["l",file] = Load file
parseInteractive ["l",file1,"|",file2] = LUnion file1 file2
parseInteractive ["l",file1," ",file2] = LProduct file1 file2
parseInteractive ["l",file, "*"] = LStar file
parseInteractive ["l",file1,".o.",file2] = LComposition file1 file2
parseInteractive ["s",file] = Save file
parseInteractive ["vt"] = ViewTransducer
parseInteractive ["vi"] = ViewInput
parseInteractive ["vo"] = ViewOutput
parseInteractive ["vr"] = ViewReg
parseInteractive ["h"] = Help
parseInteractive ["q"] = Quit
parseInteractive ["c"] = ClearMemory
parseInteractive _ = NoCommand
-- | Does the file end with .fst?
isFST :: String -> Bool
isFST = isSuffixOf ".fst"
-- | Does the file end with .dat?
isDAT :: String -> Bool
isDAT = isSuffixOf ".dat"
-- | Does the file end with .net?
isNET :: String -> Bool
isNET = isSuffixOf ".net"
-- | Is the internal transducer being specified?
isTHIS :: String -> Bool
isTHIS = (== "*")
-- | Is apply up?
isApplyUp :: [String] -> Bool
isApplyUp = elem "-u"
-- | Batch command ADT
data BatchCommand =
-- | Apply down
DownB
-- | Apply up
| UpB
-- | Invalid command
| InvalidCommand
-- | Take input from given file
| Input String
-- | Write output to file
| Output String
-- | Display help
| HelpB
deriving (Eq, Show)
-- | Information for parsing batch options
batchOptions :: [OptDescr BatchCommand]
batchOptions = [
Option ['u'] ["up"] (NoArg UpB) "apply the transducer up (default is down)",
Option ['d'] ["down"] (NoArg DownB) "apply the transducer down (default)",
Option ['i'] ["input"] (ReqArg Input "FILE") "read input from FILE",
Option ['o'] ["output"] (ReqArg Output "FILE") "write output to FILE"
]
-- | Parse batch commands
parseBatch :: [String] -> Either String (FilePath,[BatchCommand])
parseBatch cmdline = case getOpt Permute batchOptions cmdline of
(o, [file], []) -> Right (file, o)
(_, _, errs) -> Left (concat errs ++ usageInfo header batchOptions) where
header = "Usage: fst [FILE.net or FILE.fst] [OPTIONS...]"
-- | Handle batch input command
inputB :: [BatchCommand] -> Maybe FilePath
inputB cs = listToMaybe [ file | Input file <- cs ]
-- | Handle batch output command
outputB :: [BatchCommand] -> Maybe FilePath
outputB cs = listToMaybe [ file | Output file <- cs ]
-- | Is batch command apply up?
isUpB :: [BatchCommand] -> Bool
isUpB = elem UpB
{-
-----------------------------------------------------------------------------------------
-- and here a small and hopefully enlightening example:
data Flag = Verbose | Version | Name String | Output String | Arg String deriving Show
options :: [OptDescr Flag]
options =
[Option ['v'] ["verbose"] (NoArg Verbose) "verbosely list files",
Option ['V','?'] ["version","release"] (NoArg Version) "show version info",
Option ['o'] ["output"] (OptArg out "FILE") "use FILE for dump",
Option ['n'] ["name"] (ReqArg Name "USER") "only dump USER's files"]
out :: Maybe String -> Flag
out Nothing = Output "stdout"
out (Just o) = Output o
test :: ArgOrder Flag -> [String] -> String
test order cmdline = case getOpt order options cmdline of
(o,n,[] ) -> "options=" ++ show o ++ " args=" ++ show n ++ "\n"
(_,_,errs) -> concat errs ++ usageInfo header options
where header = "Usage: foobar [OPTION...] files..."
-- example runs:
-- putStr (test RequireOrder ["foo","-v"])
-- ==> options=[] args=["foo", "-v"]
-- putStr (test Permute ["foo","-v"])
-- ==> options=[Verbose] args=["foo"]
-- putStr (test (ReturnInOrder Arg) ["foo","-v"])
-- ==> options=[Arg "foo", Verbose] args=[]
-- putStr (test Permute ["foo","--","-v"])
-- ==> options=[] args=["foo", "-v"]
-- putStr (test Permute ["-?o","--name","bar","--na=baz"])
-- ==> options=[Version, Output "stdout", Name "bar", Name "baz"] args=[]
-- putStr (test Permute ["--ver","foo"])
-- ==> option `--ver' is ambiguous; could be one of:
-- -v --verbose verbosely list files
-- -V, -? --version, --release show version info
-- Usage: foobar [OPTION...] files...
-- -v --verbose verbosely list files
-- -V, -? --version, --release show version info
-- -o[FILE] --output[=FILE] use FILE for dump
-- -n USER --name=USER only dump USER's files
-----------------------------------------------------------------------------------------
test :: ArgOrder BatchCommand -> [String] -> String
test order cmdline = case getOpt order batchOptions cmdline of
(o,n,[] ) -> "options=" ++ show o ++ " args=" ++ show n ++ "\n"
(_,_,errs) -> concat errs ++ usageInfo header batchOptions
where header = "Usage: fst [OPTION...] files..."
-}