aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthew Hall <hallmatthew314@gmail.com>2023-03-17 23:54:46 +1300
committerMatthew Hall <hallmatthew314@gmail.com>2023-03-17 23:54:46 +1300
commit658876fa4db1bb8363a03135fd22ad61b25050b7 (patch)
tree79f99c99ceac77abe761903346a662c3aa788763 /src
parent72236e9bcaf7bff4a2bfbeb50ddf5d0261f74927 (diff)
recover and optional
Diffstat (limited to 'src')
-rw-r--r--src/parcom/parser.cr21
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