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".
This commit is contained in:
parent
3dca4c2166
commit
d9b50527b1
1 changed files with 12 additions and 13 deletions
25
lambda.hs
25
lambda.hs
|
|
@ -1,3 +1,4 @@
|
||||||
|
import Control.Monad
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Text.ParserCombinators.ReadP
|
import Text.ParserCombinators.ReadP
|
||||||
|
|
@ -91,22 +92,24 @@ evaluate = takeWhileUnique . iterate apply
|
||||||
- Parsing expressions
|
- 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 :: [(Char, Char)]
|
||||||
parens = [('(',')'),('[',']'),('{','}')]
|
parens = [('(',')'),('[',']'),('{','}')]
|
||||||
|
|
||||||
isOpeningParen :: Char -> Bool
|
isOpeningParen :: Char -> Bool
|
||||||
isOpeningParen a = isJust $ lookup a parens
|
isOpeningParen a = isJust $ lookup a parens
|
||||||
-- Pointfree alternative:
|
|
||||||
-- isOpeningParen = isJust . flip lookup parens
|
|
||||||
|
|
||||||
isClosingParen :: Char -> Char -> Bool
|
isClosingParen :: Char -> Char -> Bool
|
||||||
isClosingParen a b = fromMaybe False $ (==b) <$> lookup a parens
|
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 :: ReadP a -> ReadP a
|
||||||
parenthesize parser = do
|
parenthesize parser = do
|
||||||
|
|
@ -134,12 +137,8 @@ parseExpr =
|
||||||
let options = parseSymbol
|
let options = parseSymbol
|
||||||
+++ parseLambda
|
+++ parseLambda
|
||||||
+++ parenthesize parseExpr
|
+++ parenthesize parseExpr
|
||||||
-- let options = choice [parseSymbol
|
|
||||||
-- ,parseLambda
|
|
||||||
-- ,parenthesize parseExpr
|
|
||||||
-- ]
|
|
||||||
parse = between skipSpaces skipSpaces options
|
parse = between skipSpaces skipSpaces options
|
||||||
in chainl1 parse (return EExpr)
|
in chainl1' parse (return EExpr)
|
||||||
|
|
||||||
findReferences :: (Eq s) => Expression s -> Expression s
|
findReferences :: (Eq s) => Expression s -> Expression s
|
||||||
findReferences = find_ []
|
findReferences = find_ []
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue