From d9b50527b1c15e5cc676fb214504764864217896 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 25 Nov 2017 19:04:16 +0000 Subject: [PATCH] Fix parsing of expressions Previously, expressions like "\a.a b c" would wrongly get parsed to something like "(\a.a) b c" or "(\a.a b) c". --- lambda.hs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/lambda.hs b/lambda.hs index 85c61e8..31725d9 100644 --- a/lambda.hs +++ b/lambda.hs @@ -1,3 +1,4 @@ +import Control.Monad import Data.List import Data.Maybe import Text.ParserCombinators.ReadP @@ -91,22 +92,24 @@ evaluate = takeWhileUnique . iterate apply - Parsing expressions -} +-- "munchified" versions of many, many1 and chainl1 that try to match as much as possible. +many' :: ReadP a -> ReadP [a] +many' p = many1' p <++ return [] + +many1' :: ReadP a -> ReadP [a] +many1' p = liftM2 (:) p (many' p) + +chainl1' :: ReadP a -> ReadP (a -> a -> a) -> ReadP a +chainl1' p f = foldl1 <$> f <*> many1' p + parens :: [(Char, Char)] parens = [('(',')'),('[',']'),('{','}')] isOpeningParen :: Char -> Bool isOpeningParen a = isJust $ lookup a parens --- Pointfree alternative: --- isOpeningParen = isJust . flip lookup parens isClosingParen :: Char -> Char -> Bool isClosingParen a b = fromMaybe False $ (==b) <$> lookup a parens --- And as monad: --- isClosingParen a b = fromMaybe False $ do --- closing <- lookup a parens --- return $ closing == b --- And again as a monad: --- isClosingParen a b = fromMaybe False $ lookup a parens >>= return . (==b) parenthesize :: ReadP a -> ReadP a parenthesize parser = do @@ -134,12 +137,8 @@ parseExpr = let options = parseSymbol +++ parseLambda +++ parenthesize parseExpr --- let options = choice [parseSymbol --- ,parseLambda --- ,parenthesize parseExpr --- ] parse = between skipSpaces skipSpaces options - in chainl1 parse (return EExpr) + in chainl1' parse (return EExpr) findReferences :: (Eq s) => Expression s -> Expression s findReferences = find_ []