c++ - trigger warning from boost spirit parser -


how can add warnings in boost spirit parser.

edit: ... report issue position

for example if have integer parser:

('0' >> oct) | int_ 

i able this:

('0' >> oct) | "-0" --> trigger warning("negative octal values not supported, interpreted negative decimal value , leading 0 ignored") | int_ 

q. can create own callback? how?

a. sure. way you'd in c++ (or @ boost signal2 and/or boost log)

parser(std::function<bool(std::string const& s)> callback)      : parser::base_type(start),       callback(callback) {     using namespace qi;      start %=          as_string[+graph]              [ _pass = phx::bind(callback, _1) ]         % +space         ;      boost_spirit_debug_nodes((start)); } 

as can see, can make handler decide whether warning should ignored or cause match fail.


update #1 i've extended sample show of unrelated challenges mentioned in comments (position, duplicate checking). hope helps

here's simple demonstration: see live on coliru (word)

update #2 i've made (a) store source information instead of iterators, (b) made "work" floats (or other exposed attribute type, really).

note how uncannily similar is, s/word/number/, basically: live on coliru (number)

#define boost_result_of_use_decltype // needed gcc 4.7, not clang++ #define boost_spirit_use_phoenix_v3 #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/phoenix.hpp> #include <boost/spirit/include/phoenix_stl.hpp> #include <functional>  namespace qi  = boost::spirit::qi; namespace phx = boost::phoenix;  // okay, want position reporting (actually unrelated): #include <boost/spirit/include/support_line_pos_iterator.hpp> using = boost::spirit::line_pos_iterator<std::string::const_iterator>;  // ast type represents number 'token' (with source , location // information) struct number  {      double      value;     size_t      line_pos;     std::string source;      explicit number(double value = 0.0, boost::iterator_range<it> const& range = {})         :            value(value),           line_pos(get_line(range.begin())),           source(range.begin(), range.end())     {}      bool operator< (const number& other) const { return (other.value - value) > 0.0001; } };  // exposed attribute parser: using words    = std::set<number>;  // callback signature our warning; make more // `on_error` takes iterators directly, again, i'm doing // simple thing dmeo using callback = std::function<bool(number const& s)>;  template <typename it>     struct parser : qi::grammar<it, words()> {     parser(callback warning)          : parser::base_type(start),           warning(warning)     {         using namespace qi;         auto check_unique = phx::end(_val) == phx::find(_val, _1);      word   =                 raw [ double_ [ _a = _1 ] ] [ _val = phx::construct<number>(_a, _1) ]                ;          start %=                 - word        [ _pass = check_unique || phx::bind(warning, _1) ]                % +space                >> eoi                ;     }    private:     callback warning;     qi::rule<it, number(), qi::locals<double> > word;     qi::rule<it, words()> start; };  int main(int argc, const char *argv[]) {     // parse command line arguments     const auto flags          = std::set<std::string> { argv+1, argv+argc };     const bool fatal_warnings = end(flags) != flags.find("-werror");      // test input     const std::string input("2.4 2.7 \n\n\n-inf \n\nnan 88 -2.40001 \n3.14 240001e-5\n\ninf");      // warning handler     auto warning_handler = [&](number const& w) {          std::cerr << (fatal_warnings?"error":"warning")                    << ": near-identical entry '" << w.source << "' @ l:" << w.line_pos << "\n";          return !fatal_warnings;     };      // parse     f(begin(input)), l(end(input));     bool ok = qi::parse(f, l, parser<it>(warning_handler));      // report results     if (ok)   std::cout << "parse success\n";     else      std::cerr << "parse failed\n";     if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'\n";      // exit code     return ok? 0 : 255; } 

prints:

warning: near-identical entry 'nan' @ l:6 warning: near-identical entry '240001e-5' @ l:7 parse success 

Comments

Popular posts from this blog

java.util.scanner - How to read and add only numbers to array from a text file -

rewrite - Trouble with Wordpress multiple custom querystrings -

php - Accessing static methods using newly created $obj or using class Name -