Simple generic parsing functions for common searched elements.

master
Philippe Pittoli 2024-01-09 07:24:41 +01:00
parent fbfa7c7d48
commit 51fe35c60f
2 changed files with 45 additions and 29 deletions

View File

@ -47,6 +47,10 @@ main = do
Just (Tuple x y) -> show x <> " " <> show y Just (Tuple x y) -> show x <> " " <> show y
Nothing -> "failed" Nothing -> "failed"
log $ "parsing 'fic' in 'fiction' (string): " <> case parse (string "fic") "fiction" of
Just (Tuple x y) -> show x <> " " <> show y
Nothing -> "failed"
-- JUST WORKS -- JUST WORKS
-- isffound $ parse isf "fable" -- isffound $ parse isf "fable"
-- isffound $ parse isf "f" -- isffound $ parse isf "f"

View File

@ -5,14 +5,14 @@ import Prelude
import Data.Array as A import Data.Array as A
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Data.Tuple (Tuple(..)) import Data.Tuple (Tuple(..))
import Data.String.CodeUnits (uncons, toCharArray, fromCharArray) import Data.String.CodeUnits (singleton, uncons, toCharArray, fromCharArray)
newtype Parser v = Parser (String -> Maybe (Tuple v String)) newtype Parser v = Parser (String -> Maybe (Tuple v String))
parse :: forall a. Parser a -> (String -> Maybe (Tuple a String)) parse :: forall a. Parser a -> (String -> Maybe (Tuple a String))
parse (Parser p) = p parse (Parser p) = p
itemP :: Parser Char item :: Parser Char
itemP = Parser p item = Parser p
where p str = case uncons str of where p str = case uncons str of
Nothing -> Nothing Nothing -> Nothing
Just { head: x, tail: xs } -> Just (Tuple x xs) Just { head: x, tail: xs } -> Just (Tuple x xs)
@ -41,35 +41,47 @@ instance bindParser :: Bind Parser where
let (Parser p2) = f x let (Parser p2) = f x
in p2 xs in p2 xs
charP :: Char -> Parser Boolean
charP c = (_ == c) <$> itemP
-- Next steps. -- Next steps.
empty :: forall a. Parser a
empty = Parser \_ -> Nothing
sat :: (Char -> Boolean) -> Parser Char sat :: (Char -> Boolean) -> Parser Char
sat f = Parser p sat p = do x <- item
where if p x then pure x else empty
p stream = case uncons stream of
Nothing -> Nothing
Just { head: x, tail: xs } -> if f x then Just (Tuple x xs)
else Nothing
emptyP :: forall a. Parser a isDigit :: Char -> Boolean
emptyP = Parser \_ -> Nothing isDigit = between '0' '9'
sat2 :: (Char -> Boolean) -> Parser Char digit :: Parser Char
sat2 p = do x <- itemP digit = sat isDigit
if p x then pure x else emptyP
--try :: Parser a -> Parser a isLower :: Char -> Boolean
--try p = Parser p' isLower = between 'a' 'z'
-- where
-- p' = case parse p of
-- Nothing -> p
-- Just
-- orElse, (<|>) :: Parser a -> Parser a -> Parser a
stringP :: String -> Parser Boolean lower :: Parser Char
stringP str = case A.uncons (toCharArray str) of lower = sat isLower
Nothing -> Parser \stream -> Just (Tuple true stream)
Just { head: x, tail: xs } -> do _ <- charP x isUpper :: Char -> Boolean
stringP (fromCharArray xs) isUpper = between 'A' 'Z'
upper :: Parser Char
upper = sat isUpper
isAlpha :: Char -> Boolean
isAlpha c = A.any (\f -> f c) [isLower, isUpper]
letter :: Parser Char
letter = sat isAlpha
char :: Char -> Parser Char
char x = sat (_ == x)
concat :: Char -> String -> String
concat c rest = singleton c <> rest
string :: String -> Parser String
string str = case A.uncons (toCharArray str) of
Nothing -> Parser \stream -> Just (Tuple "" stream)
Just { head: x, tail: xs } -> do c <- char x
rest <- string (fromCharArray xs)
pure (concat c rest)