diff --git a/libwccl/parser/Parser.cpp b/libwccl/parser/Parser.cpp
index 66ddfab81adcfe013bc2ebdd7631eb71fd3332c4..94d6014c6e3b89caa767794a59751df7cc2d874d 100644
--- a/libwccl/parser/Parser.cpp
+++ b/libwccl/parser/Parser.cpp
@@ -134,39 +134,45 @@ boost::shared_ptr<ANTLRParserResultBase> Parser::parseAnyOperator(
 boost::shared_ptr<ANTLRParserResultBase> Parser::parseAnyOperator(
 		std::istream& istr) const
 {
+	std::stringstream ss;
+	ss << istr.rdbuf();
+	std::stringstream errors;
 	boost::shared_ptr<ANTLRParserResultBase> result;
 	if (!result) {
-		istr.seekg(0);
-		ANTLRLexer lexer(istr);
+		ss.seekg(0, std::ios::beg);
+		ANTLRLexer lexer(ss);
 		ANTLRParser parser(lexer);
 		try {
 			result = parser.parse_sym_set_operator(tagset_);
-		} catch (antlr::ANTLRException) {
+		} catch (antlr::ANTLRException& e) {
+			errors << "(as tset) " << e.getMessage() << "\n";
 			// ignore, try another type
 		}
 	}
 	if (!result) {
-		istr.clear();
-		istr.seekg(0);
-		ANTLRLexer lexer(istr);
+		ss.seekg(0, std::ios::beg);
+		ANTLRLexer lexer(ss);
 		ANTLRParser parser(lexer);
 		try {
 			result = parser.parse_string_operator(tagset_);
-		} catch (antlr::ANTLRException) {
+		} catch (antlr::ANTLRException& e) {
+			errors << "(as strset) " << e.getMessage() << "\n";
 			// ignore, try another type
 		}
 	}
 	if (!result) {
-		istr.clear();
-		istr.seekg(0);
-		ANTLRLexer lexer(istr);
+		ss.seekg(0, std::ios::beg);
+		ANTLRLexer lexer(ss);
 		ANTLRParser parser(lexer);
 		try {
 			result = parser.parse_predicates(tagset_);
-		} catch (antlr::ANTLRException) {
-			throw;
+		} catch (antlr::ANTLRException& e) {
+			errors << "(as predicate) " << e.getMessage() << "\n";
+			// ignore, try another type
 		}
 	}
-	assert(result);
+	if (!result) {
+		throw ParserException(errors.str());
+	}
 	return result;
 }