diff options
Diffstat (limited to 'src/__OLD_parcom/optional.cr')
| -rw-r--r-- | src/__OLD_parcom/optional.cr | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/__OLD_parcom/optional.cr b/src/__OLD_parcom/optional.cr new file mode 100644 index 0000000..b368d4e --- /dev/null +++ b/src/__OLD_parcom/optional.cr @@ -0,0 +1,40 @@ +require "./parser.cr" + +module Parcom + # `Optional` 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, an `Optional` will not modify the input + # stream, and return `nil` instead. + # + # Example: + # ``` + # digit = Satisfy(Char).new { |c| c.digit? } + # digits = Many.new(digit) + # plus_sign = Optional.new(Token.new('+')) + # positive_int = plus_sign >> digits + # + # input1 = Tokens.from_string("+12345") + # input2 = Tokens.from_string("12345") + # + # # Both of these has the same result + # positive_int.parse(input1) + # positive_int.parse(input2) + # ``` + class Optional(T, V) < Parser(T, V?) + # Accepts the parser to use. + def initialize(@p : Parser(T, V)) + end + + # Tries to parse with the given parser, succeeds with `nil` + # instead of failing. This parser does not consume input if + # the wrapped parser fails. + def parse(tokens : Tokens(T)) : Result(T, V?) + 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 + |
