aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spec/parcom_spec.cr23
-rw-r--r--src/parcom.cr21
2 files changed, 41 insertions, 3 deletions
diff --git a/spec/parcom_spec.cr b/spec/parcom_spec.cr
index 5be59b9..937c43c 100644
--- a/spec/parcom_spec.cr
+++ b/spec/parcom_spec.cr
@@ -378,7 +378,28 @@ describe Optional do
end
end
-pending Tokens do
+describe Tokens do
+ p = Tokens.new("test".chars)
+
+ describe "#parse" do
+ it "fails if the input stream is too short" do
+ input = TokenStream.from_string("")
+ expect_raises(ParserException) { p.parse(input) }
+ end
+
+ it "fails if it encounters an unexpected token" do
+ input = TokenStream.from_string("text")
+ expect_raises(ParserException) { p.parse(input) }
+ end
+
+ it "succeeds if the input starts with the expected tokens" do
+ input = TokenStream.from_string("testing")
+ result = p.parse(input)
+
+ result.tokens.should eq(input[4..])
+ result.value.should eq("test".chars)
+ end
+ end
end
pending Many do
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