blob: b70164fc197c769a7e10bcc9319557d2e16c8e0e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
|