require "./parser.cr" require "./optional.cr" require "./map.cr" module Parcom # `Recover` is a `Parser` that tries to parse with another parser, # but does not fail the parser chain if the wrapped parser fails. # If the wrapped parser fails, a `Recover` will not modify the input # stream, and return an arbitrary value of type `V` instead. class Recover(T, V) < Parser(T, V) @p : Map(T, V?, V) # Accepts the parser to use, and the default value # to return if the parser fails. def initialize(p : Parser(T, V), default : V) @p = Optional.new(p).map { |x| x.nil? ? default : x } end # Tries to parse with the given parser, succeeds with the # default value instead of failing. This parser does not # consume input if the wrapped parser fails. def parse(tokens : Tokens(T)) : Result(T, V) @p.parse(tokens) end end end