diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/parcom/parser.cr | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/src/parcom/parser.cr b/src/parcom/parser.cr index fcfe292..8ee3f68 100644 --- a/src/parcom/parser.cr +++ b/src/parcom/parser.cr @@ -241,6 +241,29 @@ module Parcom p1 = self (p1 + p2).map(&.last).named("#{p1.name} >> #{p2.name}") end + + # Creates a new parser from `self` that parses with `self` as many times + # as possible. If it never succeeds, returns an empty list. + def many : Parser(T, Array(U)) + p = self + Parser(T, Array(U)).new("Many: #{p.name}") do |tokens| + values = [] of U + r = p.parse?(tokens) + until r.nil? + break unless tokens != r.tokens + tokens = r.tokens + values << r.value + r = p.parse?(tokens) + end + Result.new(tokens, values) + end + end + + # Creates a new parser from `self` that parses with `self` as many times + # as possible. Raises `ParserFail` it never succeeds. + def some : Parser(T, Array(U)) + many.assert { |arr| !arr.empty? }.named("Some: #{@name}") + end end end |
