diff options
| author | Matthew Hall <hallmatthew314@gmail.com> | 2023-03-19 22:13:13 +1300 |
|---|---|---|
| committer | Matthew Hall <hallmatthew314@gmail.com> | 2023-03-19 22:13:13 +1300 |
| commit | 54263a0cfec5ef1adcd1bf6541abc0275d9a98df (patch) | |
| tree | 9ea63fc9aa2463d41e3beedaee833a51109695a4 /src | |
| parent | acd14e4b4f722f7fe502bbf3aabab16d7d7df396 (diff) | |
first_of
Diffstat (limited to 'src')
| -rw-r--r-- | src/parcom/parser.cr | 21 |
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)) |
