packages feed

fudgets-0.18.3: Demos/graph/Parsop.hs

module	Parsop where
infixl |||, +++, +>+, +<+
{-
infix "==>";
prefix "***";
infix "+<+";
infix "+>+";
infix "iff";
prefix "%%";
-}
{-
export	empty,
-- matches the empty string
	+++,
-- sequence, returns a pair
	|||,
-- alternative
	is,
-- terminal tested with a predicate
	`,
-- terminal tested with equality
	***,
-- 0 or many (transitive closure)
	+<+,
-- sequence, throw away first part
	+>+,
-- sequence, throw away second part
	==>,
-- transform
	cond,
-- 0 or one
	seq',
-- sequence of 0 or many with a separator
	seq1,
-- sequence of 1 or many with a separator
	iff,
-- conditional
	%%;
-- uncurry
-}
trycase pf fail succeed ws=
  case pf ws of
     Left _ -> fail ws
     Right(x,ws) -> succeed x ws


failure ws= Left ws
success x ws = Right(x,ws)

try pf cont = trycase pf failure cont

is p [] = Left []
is p (w:ws) = if p w
		  then Right(w,ws)
		  else Left (w:ws)

lit w = is (==w)

pf1 +++ pf2 = try pf1 (\x ->try pf2 (\y -> success(x,y)))

pf1 ||| pf2 = trycase pf1 pf2 success

pf ==> f = try pf (success . f)

(***) pf = ((pf +++ (***) pf) ==> (%%) (:)) ||| success []

sep +<+ pf1 = (sep +++ pf1) ==> snd
pf1 +>+ sep = (pf1 +++ sep) ==> fst

--seq1 pf sep = ((pf +++ (sep +<+ seq1 pf sep)) ==> %% (.)) ||| (pf ==> (:[]))
seq1 pf sep = (pf +++ ((sep +<+ seq1 pf sep) ||| empty [])) ==> (%%) (:)

seq' pf sep = seq1 pf sep ||| empty []

empty = success

cond pf x = pf ||| empty x

pf `iff` p = try pf (\x -> if p x
			  then success x
			  else failure)

(%%) = uncurry