aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthew Hall <hallmatthew314@gmail.com>2023-03-18 22:47:02 +1300
committerMatthew Hall <hallmatthew314@gmail.com>2023-03-18 22:47:02 +1300
commit6406766e5a175c87dfc20c1ff1374c8c8a163517 (patch)
tree4c8e841b0d312ce46245f9748bd4057fb38581b1 /src
parent467660e024bad8e2e084aa703686d0856a7e88b9 (diff)
Many and Some
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