aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthew Hall <hallmatthew314@gmail.com>2023-03-09 01:44:06 +1300
committerMatthew Hall <hallmatthew314@gmail.com>2023-03-09 01:44:06 +1300
commitf5e87b41ffcb036c705c32b55161ae91a04c72e1 (patch)
tree334cdcc5b8ee1c773a9ee0418b4e744f7d7f2f73 /src
parent27a2d4281c5b270d6f3bba06ff1fd82ebfb94df6 (diff)
Implement Token sequence parser
Diffstat (limited to 'src')
-rw-r--r--src/parcom.cr21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/parcom.cr b/src/parcom.cr
index 14d2e44..760a450 100644
--- a/src/parcom.cr
+++ b/src/parcom.cr
@@ -133,7 +133,7 @@ module Parcom
result = @p.parse(tokens)
unless @f.call(result.value)
- raise ParserException.new("Assert: predicate failed")
+ raise ParserException.new("Assert: predicate failed for <#{result.value}>")
end
result
@@ -153,6 +153,8 @@ module Parcom
def parse(tokens : TokenStream(T)) : Result(T, T)
@p.parse(tokens)
+ rescue ex : ParserException
+ raise ParserException.new("Token <#{@expected}>: #{ex.message}")
end
end
@@ -226,7 +228,22 @@ module Parcom
end
end
- class Tokens
+ class Tokens(T) < Parser(T, Array(T))
+ def initialize(@expected : Iterable(T))
+ end
+
+ # TODO: this can probably be optimised more for Arrays
+ # TODO: might be better to use #zip?
+ def parse(tokens : TokenStream(T)) : Result(T, Array(T))
+ parsed_tokens = [] of T
+
+ @expected.each_with_index do |t, i|
+ r = Token.new(t).parse(tokens[i..])
+ parsed_tokens << r.value
+ end
+
+ Result.new(tokens[parsed_tokens.size..], parsed_tokens)
+ end
end
class Many