aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthew Hall <hallmatthew314@gmail.com>2023-03-19 22:13:13 +1300
committerMatthew Hall <hallmatthew314@gmail.com>2023-03-19 22:13:13 +1300
commit54263a0cfec5ef1adcd1bf6541abc0275d9a98df (patch)
tree9ea63fc9aa2463d41e3beedaee833a51109695a4 /src
parentacd14e4b4f722f7fe502bbf3aabab16d7d7df396 (diff)
first_of
Diffstat (limited to 'src')
-rw-r--r--src/parcom/parser.cr21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/parcom/parser.cr b/src/parcom/parser.cr
index 0b09e95..95a2e21 100644
--- a/src/parcom/parser.cr
+++ b/src/parcom/parser.cr
@@ -112,6 +112,27 @@ module Parcom
Parser(T, T).sequence(ps).named("Token Sequence: #{ts}")
end
+ # TODO: Allow support for Iterable(Parser(T, U))
+ def self.first_of(ps : Array(Parser(T, U))) : Parser(T, U)
+ if ps.empty?
+ raise ArgumentError.new("first_of requires at least one parser")
+ end
+
+ Parser(T, U).new("First of: #{ps.map(&.name)}") do |tokens|
+ result = nil
+ ps.each do |p|
+ break unless result.nil?
+ result = result || p.parse?(tokens)
+ end
+
+ if result.nil?
+ raise ParserFail.new("No successes from any provided parsers.")
+ else
+ result
+ end
+ end
+ end
+
# Creates a new parser from a `Proc`.
# The `Proc` should have the properties outlined above.
def initialize(@name : String, @f : Tokens(T) -> Result(T, U))