aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spec/parcom_spec.cr25
-rw-r--r--src/parcom.cr14
2 files changed, 37 insertions, 2 deletions
diff --git a/spec/parcom_spec.cr b/spec/parcom_spec.cr
index f35465c..c395636 100644
--- a/spec/parcom_spec.cr
+++ b/spec/parcom_spec.cr
@@ -310,7 +310,30 @@ describe Plus do
end
end
-pending Phrase do
+describe Phrase do
+ p = Phrase.new(Token.new('t'))
+
+ describe "#parse" do
+ it "fails if the wrapped parser fails" do
+ tokens = TokenStream.from_string("_")
+
+ expect_raises(ParserException) { p.parse(tokens) }
+ end
+
+ it "fails if not all of the input tokens are parsed" do
+ tokens = TokenStream.from_string("tt")
+
+ expect_raises(ParserException) { p.parse(tokens) }
+ end
+
+ it "succeeds if the wrapped parser successfully parses all of the input" do
+ tokens = TokenStream.from_string("t")
+ result = p.parse(tokens)
+
+ result.tokens.empty?.should be_true
+ result.value.should eq('t')
+ end
+ end
end
pending Recover do
diff --git a/src/parcom.cr b/src/parcom.cr
index 8d1d47b..4d49a97 100644
--- a/src/parcom.cr
+++ b/src/parcom.cr
@@ -166,7 +166,19 @@ module Parcom
end
end
- class Phrase
+ class Phrase(T, V)
+ def initialize(@p : Parser(T, V))
+ end
+
+ def parse(tokens : TokenStream(T)) : Result(T, V)
+ r = @p.parse(tokens)
+
+ unless r.tokens.empty?
+ raise ParserException.new("Phrase: some of the input was not parsed")
+ end
+
+ r
+ end
end
class Plus(T, V, U) < Parser(T, {V, U})