diff options
| author | Matthew Hall <hallmatthew314@gmail.com> | 2023-03-17 23:54:46 +1300 |
|---|---|---|
| committer | Matthew Hall <hallmatthew314@gmail.com> | 2023-03-17 23:54:46 +1300 |
| commit | 658876fa4db1bb8363a03135fd22ad61b25050b7 (patch) | |
| tree | 79f99c99ceac77abe761903346a662c3aa788763 /src | |
| parent | 72236e9bcaf7bff4a2bfbeb50ddf5d0261f74927 (diff) | |
recover and optional
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 |
