Browse files

! Fixes issue #18

An UnconsumedInput error is now raised when there is input left at the end of
a successful parse.
  • Loading branch information...
1 parent ad967b4 commit ac3a4fcec8cf7adbe2d7dc46c95948a1235422b7 @kschiess committed Jun 5, 2011
View
8 lib/parslet.rb
@@ -75,6 +75,14 @@ def self.included(base) # :nodoc:
class ParseFailed < StandardError
end
+ # Raised when the parse operation didn't consume all of its input. In this
+ # case, it makes only limited sense to look at the error tree. Maybe the
+ # parser worked just fine, but didn't account for the characters at the tail
+ # of the input?
+ #
+ class UnconsumedInput < ParseFailed
+ end
+
module ClassMethods
# Define an entity for the parser. This generates a method of the same
# name that can be used as part of other patterns. Those methods can be
View
12 lib/parslet/atoms/base.rb
@@ -48,14 +48,16 @@ def parse(io)
# error to fail with. Otherwise just report that we cannot consume the
# input.
if cause
- # Don't garnish the real cause; but the exception is different anyway.
- raise Parslet::ParseFailed,
+ # We're not using #parse_failed here, since it assigns to @last_cause.
+ # Still: We'll raise this differently, since the real cause is different.
+ raise Parslet::UnconsumedInput,
"Unconsumed input, maybe because of this: #{cause}"
else
old_pos = source.pos
parse_failed(
format_cause(source,
- "Don't know what to do with #{source.read(100)}", old_pos))
+ "Don't know what to do with #{source.read(100)}", old_pos),
+ Parslet::UnconsumedInput)
end
end
@@ -246,9 +248,9 @@ def error(source, str, pos=nil)
# Signals to the outside that the parse has failed. Use this in conjunction
# with #format_cause for nice error messages.
#
- def parse_failed(cause)
+ def parse_failed(cause, exception_klass=Parslet::ParseFailed)
@last_cause = cause
- raise Parslet::ParseFailed,
+ raise exception_klass,
@last_cause.to_s
end
View
2 lib/parslet/convenience.rb
@@ -25,6 +25,8 @@ class Parslet::Atoms::Base
#
def parse_with_debug str
parse str
+ rescue Parslet::UnconsumedInput => error
+ puts error
rescue Parslet::ParseFailed => error
puts error
puts error_tree
View
12 spec/acceptance/regression_spec.rb
@@ -204,4 +204,16 @@ class UnicodeSentenceLanguage < Parslet::Parser
subject.should parse(string)
end
end
+
+ class TwoCharLanguage < Parslet::Parser
+ root :twochar
+ rule(:twochar) { any >> str('2') }
+ end
+ describe TwoCharLanguage do
+ it "should raise UnconsumedInput" do
+ expect {
+ subject.parse('123')
+ }.to raise_error(Parslet::UnconsumedInput)
+ end
+ end
end
View
5 spec/parslet/convenience_spec.rb
@@ -33,6 +33,11 @@ class FooParser < Parslet::Parser
parser.parse_with_debug('incorrect')
end
+ it "should puts once for the error on unconsumed input" do
+ parser.should_receive(:puts).once
+
+ parser.parse_with_debug('foobar')
+ end
end
it "should work for all parslets" do

0 comments on commit ac3a4fc

Please sign in to comment.