diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/parcom/parser.cr | 21 |
1 files changed, 18 insertions, 3 deletions
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 |
