diff options
| -rw-r--r-- | src/parcom.cr | 14 | ||||
| -rw-r--r-- | src/parcom/at_most.cr | 29 |
2 files changed, 29 insertions, 14 deletions
diff --git a/src/parcom.cr b/src/parcom.cr index cc123fd..24fb76c 100644 --- a/src/parcom.cr +++ b/src/parcom.cr @@ -81,20 +81,6 @@ module Parcom end end - class AtMost(T, V) < Parser(T, Array(V)) - @p : Map(T, Array(V?), Array(V)) - - def initialize(i : Int, p : Parser(T, V)) - @p = Exactly.new(i, Optional.new(p)).map(&.compact) - end - - def parse(tokens : Tokens(T)) : Result(T, Array(V)) - @p.parse(tokens) - rescue ex : ParserFail - raise ParserFail.new("AtMost: #{ex.message}") - end - end - class Between(T, V) < Parser(T, Array(V)) @p : Map(T, {Array(V), Array(V)}, Array(V)) diff --git a/src/parcom/at_most.cr b/src/parcom/at_most.cr new file mode 100644 index 0000000..b70164f --- /dev/null +++ b/src/parcom/at_most.cr @@ -0,0 +1,29 @@ +require "./parser.cr" +require "./map.cr" +require "./exactly.cr" +require "./optional.cr" + +module Parcom + # `AtMost` is a `Parser` that tries to parse with another parser a specific + # number of times. The results of each successful parse are returned in an + # array. If the specific number of parses succeed, the parsing stops, even + # if it is possible to keep parsing. If the parser is never successful, it + # succeeds with an empty array. + class AtMost(T, V) < Parser(T, Array(V)) + @p : Map(T, Array(V?), Array(V)) + + # Accepts the number of parsing attempts, and the parser to use. + def initialize(i : Int, p : Parser(T, V)) + @p = Exactly.new(i, Optional.new(p)).map(&.compact) + end + + # Tries to parse up to the given number of times. + # If the parser never succeeds, returns an empty array. + def parse(tokens : Tokens(T)) : Result(T, Array(V)) + @p.parse(tokens) + rescue ex : ParserFail + raise ParserFail.new("AtMost: #{ex.message}") + end + end +end + |
