`rollback` and `until`

master
Philippe Pittoli 2024-01-25 06:36:24 +01:00
parent 6708b2169a
commit 540b1c1962
4 changed files with 21 additions and 6 deletions

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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