diff --git a/src/GenericParser.purs b/src/GenericParser.purs index dcbe635..6cebe7a 100644 --- a/src/GenericParser.purs +++ b/src/GenericParser.purs @@ -6,4 +6,4 @@ module GenericParser import GenericParser.DomainParser.Common (DomainError(..), ldh_str, let_dig, let_dig_hyp, max_domain_length, max_label_length, Size) import GenericParser.DomainParser (domain, label, subdomain, sub_eof) -import GenericParser.Parser (alphanum, char, current_input, current_position, digit, eof, Error, failure, failureError, ident, identifier, Input, int, integer, item, letter, lower, many1, nat, natural, parse, parse_last_char, Parser(..), Position, PositionString, Result, sat, space, string, success, symbol, token, try, tryMaybe, upper, Value) +import GenericParser.Parser (alphanum, char, current_input, current_position, digit, eof, Error, failure, failureError, ident, identifier, Input, int, integer, item, letter, lower, many1, nat, natural, parse, parse_last_char, Parser(..), Position, PositionString, Result, rollback, sat, space, string, success, symbol, token, try, tryMaybe, until, upper, Value) diff --git a/src/GenericParser/DomainParser.purs b/src/GenericParser/DomainParser.purs index 1e95eee..80d655a 100644 --- a/src/GenericParser/DomainParser.purs +++ b/src/GenericParser/DomainParser.purs @@ -6,8 +6,6 @@ import Prelude (bind, not, pure, ($), (&&), (*>), (<<<), (<>), (>), (-)) import Control.Alt ((<|>)) import Control.Lazy (defer) -import Data.Array as A -import Data.Either (Either(..)) import Data.Maybe (Maybe(..), maybe) import Data.String as S import Data.String.CodeUnits as CU diff --git a/src/GenericParser/EmailAddress.purs b/src/GenericParser/EmailAddress.purs index 45c37fa..98ccdf9 100644 --- a/src/GenericParser/EmailAddress.purs +++ b/src/GenericParser/EmailAddress.purs @@ -31,7 +31,7 @@ email :: Parser EmailError String email = do login <- login_part _ <- char '@' input <- current_input - case parse sub_eof { string: input.string, position: input.position } of + case parse sub_eof input of Left {error, position} -> Parser \_ -> failureError position (Just $ InvalidDomain error) Right {result} -> pure $ login <> "@" <> result diff --git a/src/GenericParser/Parser.purs b/src/GenericParser/Parser.purs index 8b973f4..f7a8779 100644 --- a/src/GenericParser/Parser.purs +++ b/src/GenericParser/Parser.purs @@ -3,12 +3,12 @@ import Prelude import Control.Alt (class Alt, (<|>)) import Control.Alternative (class Alternative) -import Control.Lazy (class Lazy) +import Control.Lazy (class Lazy, defer) import Control.Plus (class Plus, empty) import Data.Array as A import Data.Either (Either(..)) import Data.Int as Int -import Data.Maybe (Maybe(..)) +import Data.Maybe (Maybe(..), maybe) import Data.String as S import Data.String.CodeUnits (toCharArray, fromCharArray, singleton) @@ -42,6 +42,12 @@ current_position = Parser \input -> success input input.position current_input :: forall e. Parser e Input current_input = Parser \input -> success input input +-- | `rollback` replaces the current input. +-- | +-- | This function cannot fail since no parsing is performed. +rollback :: forall e. Input -> Parser e Unit +rollback newinput = Parser \_ -> success newinput unit + -- | Fail with a specified error. -- | When a parsing has a specified error, no alternative will be tried and the error is reported. failureError :: forall e v. Position -> Maybe e -> Result e v @@ -212,6 +218,17 @@ many1 p = do first <- p rest <- A.many p pure $ A.cons first rest +-- | TODO: `until` +until :: forall e v. Parser e v -> Parser e v -> Parser e (Array v) +until parser_end p = do + input <- current_input + case parse parser_end input of + Left _ -> do v <- p + mayberest <- tryMaybe $ defer \_ -> until parser_end p + pure $ [v] <> maybe [] id mayberest + Right _ -> Parser \_ -> failure input.position + where id x = x + -- | Parse the last character of a String. -- | Return false in case the string is empty. parse_last_char :: forall e. String -> Parser e Char -> Boolean