aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parcom/parser.cr16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/parcom/parser.cr b/src/parcom/parser.cr
index d9919e1..d91ac84 100644
--- a/src/parcom/parser.cr
+++ b/src/parcom/parser.cr
@@ -255,7 +255,7 @@ module Parcom
end
# Same as `#+`, but discards the second parser's result.
- def <<(p2 : Parser(T, V)) : Parser(T, U) forall V
+ def <<(p2 : Parser(T, _)) : Parser(T, U)
p1 = self
(p1 + p2).map(&.first).named("#{p1.name} << #{p2.name}")
end
@@ -267,7 +267,7 @@ module Parcom
end
# Creates a new parser from `self` that parses with `self` as many times
- # as possible. If it never succeeds, returns an empty list.
+ # as possible. Returns an empty list if it never succeeds.
def many : Parser(T, Array(U))
p = self
Parser(T, Array(U)).new("Many: #{p.name}") do |tokens|
@@ -371,7 +371,6 @@ module Parcom
min = n < m ? n : m
extra = (n - m).abs
- p = self
(exactly(min) + at_most(extra)).map do |t|
t.first + t.last
end.named("Between #{min}-#{extra} <#{@name}>")
@@ -412,6 +411,17 @@ module Parcom
at_least(r.begin).named("Between #{r.begin}-infinity <#{@name}> (from inifnite range)")
end
+
+ # Creates a new parser from `self` and another parser that tries to
+ # parse with `self` repeatedly, alternating with `sep` and discarding
+ # the results of `sep`. This parser will fail if it cannot parse the first
+ # instance of `self`. It will succeed if it can parse an instance of `self`
+ # that is not followed by any `sep` instances.
+ def sep_by(sep : Parser(T, _)) : Parser(T, Array(U))
+ (self + (sep >> self).many).map do |tup|
+ tup.last.unshift(tup.first)
+ end.named("<#{@name}> sep by <#{sep.name}>")
+ end
end
end