require "./parser.cr" require "./any_token.cr" require "./assert.cr" module Parcom # `Satisfy` is a `Parser` that parses a single token # if that token passes a predefined test, similar # to `Assert`. This class is effectively a shorthand # for the following: # ``` # # These parsers are equivalent. # letter_assert = Assert.new(AnyToken(Char).new) { |x| x.letter? } # letter_satisfy = Satisfy(Char).new { |x| x.letter? } # ``` class Satisfy(T) < Parser(T, T) @p : Assert(T, T) # Accepts the `Bool`-returning block containing the test # to run on the parsed token. def initialize(&block : T -> Bool) @p = AnyToken(T).new.assert(&block) end # Returns the first token of the input if that # token passes the test. def parse(tokens : Tokens(T)) : Result(T, T) @p.parse(tokens) rescue ex : ParserFail raise ParserFail.new("Satisfy: #{ex.message}") end end end