require "./parser.cr" require "./sequence.cr" module Parcom # `TokenSeq` is a `Parser` that attempts to parse a specific # string of tokens. If the expected tokens are not at the start # of the input stream, the parser fails. # # Example: # ``` # parse_test = TokenSeq(Char).new("test".chars) # tokens = Tokens.from_string("testing") # # result = parse_test.parse(tokens) # # puts result.value # => ['t', 'e', 's', 't'] # puts result.tokens # => ['i', 'n', 'g'] # ``` class TokenSeq(T) < Parser(T, Array(T)) @p : Sequence(T, T) # Accepts the tokens to try and parse, in order. def initialize(expected : Iterable(T)) ps = [] of Parser(T, T) expected.each { |t| ps << Token.new(t) } @p = Sequence.new(ps) end # Tries to parse the list of tokens. def parse(tokens : Tokens(T)) : Result(T, Array(T)) @p.parse(tokens) rescue ex : ParserFail raise ParserFail.new("TokenSeq: #{ex.message}") end end end