From c9cf7815de58db9e9981569da82b5b0380d8b54c Mon Sep 17 00:00:00 2001 From: Philippe Pittoli Date: Tue, 9 Jan 2024 08:44:39 +0100 Subject: [PATCH] Lacks Control.Lazy and our parser will be full-featured. --- spago.dhall | 10 +++++++++- src/Main.purs | 4 ---- src/Parser.purs | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/spago.dhall b/spago.dhall index 2135b89..a5cc9fb 100644 --- a/spago.dhall +++ b/spago.dhall @@ -12,7 +12,15 @@ to generate this file without the comments in this block. -} { name = "parser" , dependencies = - [ "arrays", "console", "effect", "maybe", "prelude", "strings", "tuples" ] + [ "arrays" + , "console" + , "control" + , "effect" + , "maybe" + , "prelude" + , "strings" + , "tuples" + ] , packages = ./packages.dhall , sources = [ "src/**/*.purs", "test/**/*.purs" ] } diff --git a/src/Main.purs b/src/Main.purs index ae48c38..aae686d 100644 --- a/src/Main.purs +++ b/src/Main.purs @@ -39,10 +39,6 @@ main :: Effect Unit main = do log "🍝" - log $ "parsing 'hello': " <> case parse (stringP "hello") "hello" of - Just (Tuple x y) -> show x <> " " <> show y - Nothing -> "failed" - log $ "parsing the first 'f' in 'fiction' (sat): " <> case parse (sat (\x -> x == 'f')) "fiction" of Just (Tuple x y) -> show x <> " " <> show y Nothing -> "failed" diff --git a/src/Parser.purs b/src/Parser.purs index 7aaf11a..3205729 100644 --- a/src/Parser.purs +++ b/src/Parser.purs @@ -2,6 +2,11 @@ module Parser where import Prelude +import Control.Alt (class Alt) +import Control.Plus (class Plus, empty) +import Control.Alternative (class Alternative) +-- TODO: import Control.Lazy (class Lazy) + import Data.Array as A import Data.Maybe (Maybe(..)) import Data.Tuple (Tuple(..)) @@ -41,9 +46,25 @@ instance bindParser :: Bind Parser where let (Parser p2) = f x in p2 xs --- Next steps. -empty :: forall a. Parser a -empty = Parser \_ -> Nothing +instance altParser :: Alt Parser where + alt :: forall a. Parser a -> Parser a -> Parser a + alt (Parser p1) (Parser p2) = Parser p + where + p stream = case p1 stream of + Nothing -> p2 stream + Just x -> Just x + +instance plusParser :: Plus Parser where + empty :: forall a. Parser a + empty = Parser \_ -> Nothing + +instance alternativeParser :: Alternative Parser + +-- TODO: Control.Lazy instance +--instance lazyParser :: Lazy Parser (Array a) where +-- defer + +-- Generic parsing functions. sat :: (Char -> Boolean) -> Parser Char sat p = do x <- item @@ -73,6 +94,12 @@ isAlpha c = A.any (\f -> f c) [isLower, isUpper] letter :: Parser Char letter = sat isAlpha +isAlphaNum :: Char -> Boolean +isAlphaNum c = A.any (\f -> f c) [isAlpha, isDigit] + +alphanum :: Parser Char +alphanum = sat isAlphaNum + char :: Char -> Parser Char char x = sat (_ == x) @@ -85,3 +112,18 @@ string str = case A.uncons (toCharArray str) of Just { head: x, tail: xs } -> do c <- char x rest <- string (fromCharArray xs) pure (concat c rest) + +-- TODO: A.many requires an instance of Control.Lazy class. +--ident :: Parser String +--ident = do x <- lower +-- xs <- A.many alphanum +-- pure (fromCharArray $ A.cons x xs) + +-- TODO: try orElse +--try :: Parser a -> Parser a +--try p = Parser p' +-- where +-- p' = case parse p of +-- Nothing -> p +-- Just +-- orElse, (<|>) :: Parser a -> Parser a -> Parser a