require "./parser.cr" module Parcom # `Alt` is a `Parser` that accepts two other parsers and tries # to parse with one of them. # If the first (left) parser succeeds, its result is returned. # If the first parser fails, it will try the second (right) parser. class Alt(T, V) < Parser(T, V) # Accepts the two parsers to try to parse with. def initialize(@p1 : Parser(T, V), @p2 : Parser(T, V)) end # Tries to parse using both parsers. # # It will initially try to parse with the first parser. # If it fails, it will try to parse with the second parser. def parse(tokens : Tokens(T)) : Result(T, V) @p1.parse(tokens) rescue ex1 : ParserFail begin @p2.parse(tokens) rescue ex2 : ParserFail raise ParserFail.new("Alt (#{ex1.message}), (#{ex2.message})") end end end end