From 658876fa4db1bb8363a03135fd22ad61b25050b7 Mon Sep 17 00:00:00 2001 From: Matthew Hall Date: Fri, 17 Mar 2023 23:54:46 +1300 Subject: recover and optional --- src/parcom/parser.cr | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/parcom/parser.cr b/src/parcom/parser.cr index 3098080..b78ab77 100644 --- a/src/parcom/parser.cr +++ b/src/parcom/parser.cr @@ -169,9 +169,24 @@ module Parcom # Creates a new parser that is the same as the parser object it is # called from, but it will return a default value without consuming # any input instead of failing. - #def recover(default : U) : Parser(T, U) - # nil - #end + def recover(default : U) : Parser(T, U) + r = Parser(T, U).pure(default) + (self | r).named("#{@name} (recover <#{default}>)") + end + + # Creates a new parser that is the same as the parser object it is + # called from, but it will return `nil` without consuming any input + # instead of returning. + def optional : Parser(T, U?) + p = self + Parser(T, U?).new("#{p.name} (optional)") do |tokens| + # We have to do it this way due to how type unions work. + r = p.parse?(tokens) + new_tokens = r.nil? ? tokens : r.tokens + new_value = r.nil? ? nil : r.value + Result.new(new_tokens, new_value) + end + end end end -- cgit v1.2.1