From 54263a0cfec5ef1adcd1bf6541abc0275d9a98df Mon Sep 17 00:00:00 2001 From: Matthew Hall Date: Sun, 19 Mar 2023 22:13:13 +1300 Subject: first_of --- src/parcom/parser.cr | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src') 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)) -- cgit v1.2.1