Boost :: Spirit uygulamasında, 'u Boost::Bind
ile bağlı bir işlevden nasıl tetikleyebilirim?Boost Spirit'de bir işlevden beklenti_failesi nasıl atılır?
Arka plan: Karmaşık girdiler içeren büyük bir dosyayı ayrıştırıyorum. Bir giriş bir önceki girişle tutarsız olduğunda, başarısız olmak ve bir expectation_failure
(uygun ayrıştırma konum bilgisi içeren) atmak istiyorum. Bir girişi ayrıştırdığımda, girişin daha önce görülen bir şeyle tutarsız olup olmadığına karar veren bir işlevi bağlarım.
Bu noktayı gösteren küçük bir oyuncak örneği hazırladım.
: Birexpectation_failure
Fırlatma
#include <iostream>
#include <iomanip>
#include <boost/spirit/include/qi.hpp>
#include <boost/bind.hpp>
#include <boost/spirit/include/classic_position_iterator.hpp>
namespace qi = boost::spirit::qi;
namespace classic = boost::spirit::classic;
void checkNum(int const& i) {
if (i % 10 != 0) // >> How to throw proper expectation_failure? <<
std::cerr << "ERROR: Number check failed" << std::endl;
}
template <typename Iterator, typename Skipper>
struct MyGrammar : qi::grammar<Iterator, int(), Skipper> {
MyGrammar() : MyGrammar::base_type(start) {
start %= qi::eps > qi::int_[boost::bind(&checkNum, _1)];
}
qi::rule<Iterator, int(), Skipper> start;
};
template<class PosIter>
std::string errorMsg(PosIter const& iter) {
const classic::file_position_base<std::string>& pos = iter.get_position();
std::stringstream msg;
msg << "parse error at file " << pos.file
<< " line " << pos.line << " column " << pos.column << std::endl
<< "'" << iter.get_currentline() << "'" << std::endl
<< std::setw(pos.column) << " " << "^- here";
return msg.str();
}
int main() {
std::string in = "11";
typedef std::string::const_iterator Iter;
typedef classic::position_iterator2<Iter> PosIter;
MyGrammar<PosIter, qi::space_type> grm;
int i;
PosIter it(in.begin(), in.end(), "<string>");
PosIter end;
try {
qi::phrase_parse(it, end, grm, qi::space, i);
if (it != end)
throw std::runtime_error(errorMsg(it));
} catch(const qi::expectation_failure<PosIter>& e) {
throw std::runtime_error(errorMsg(e.first));
}
return 0;
}
Ben 10 ile bölünebilir olmayan bir int üzerinde böyle bir hata mesajı almak anlamına gelir: int
değil bölünebilir 10 tarafından olduğunda İşte ben sadece bir expectation_failure
atmak istiyorum
parse error at file <string> line 1 column 2
'11'
^- here
Int_ yerine başka bir kural oluşturabilir, tamsayı yalnızca durumunuz memnun olduğunda eşleşir mi? Ruh'u iyi bilmiyorum, ama AX'de r_bool'a benzer bir kural olduğunu varsayardım, bu da bir yüklemi tamamlar, oldukça yaygın bir durumdur. –
Sanırım böyle bir şeye ihtiyacım var, maalesef: http://boost-spirit.com/home/articles/qi-example/creating-your-own-parser-component-for-spirit-qi/ – Frank
Üzgünüz bakın, bu çok kullanıcı düşmanca. İşte bu yüzden AX :-) –