aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parcom/parser.cr23
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