module CmdLineParser4(
-- Parser type:
P,
-- Parser constructors:
token,cmd,(!),(<@),(#@),chk,nil,many,arg,kw,opt,flag,(--:),
-- Parser destructors:
run,usage,parseAll
) where
import Pretty
import Monad(msum,join,liftM,MonadPlus(..),ap)
import Maybe(isJust)
import System(getArgs)
import PM
import Grammar
infixl 3 <@,`chk`,#@
infix 2 --:
infixr 1 !
nil x = P Empty (return x)
P g1 f <@ P g2 a = P (Seq g1 g2) (f `ap` a)
named nt (P g p) = P (Nonterminal nt g) p
P g p --: descr = P (g :--- descr) p
token f s = P (Terminal s) (tokenP f s)
P g1 p1 ! P g2 p2 = P (Alt g1 g2) (p1 `mplus` p2)
many (P g p) = P (Many g) (manyP p)
opt (P g p) = P (Opt g) (fmap Just p `mplus` return Nothing)
chk p p' = const `fmap` p <@ p'
cmd s p = nil p `chk` kw s
f #@ p = fmap f p
arg = token Just
kw s = token check s
where check a = if a==s then Just () else Nothing
flag s = isJust `fmap` opt (kw s)
usage prefix p = render (usageDoc prefix p)
usageDoc prefix (P g _) =
(text "Usage:" $$
nest 2 (nest 2 (text prefix<+>main) $$
if null aux then empty else text "where" $$ vcat aux))
where
(main,aux) = ppGrammar g