1

EBNF rule for XML comment tag is:

Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'

How to get Boost Spirit Qi rule for it?

using boost::spirit::qi::ascii::char_;
using boost::spirit::qi::lit;
comment = lit("<!--") >> *((~char_('-') >> char_) | (char_('-') >> ~char_('-'))) >> lit("-->");

This is my the best try, but not correct...

ShiS
  • 13
  • 4

2 Answers2

1

~char_('-') corresponds to (Char - '-').
The first part:

(~char_('-') >> char_)

should be

~char_('-')

alone.

Otherwise this char_ could match a - and the second part (char_('-') >> ~char_('-') match -> on the next turn.

O'Neil
  • 3,790
  • 4
  • 16
  • 30
  • 1
    I agree, the first part should be `~char_('-')`, but in this case `*(~char_('-') | (char_('-') >> ~char_('-')))` compilation fails — because the first part produces one symbol and the second two. Some attempts to use expectation parser (`>`) or/and `omit[]` in the second were unsuccessful.Thank you anyway. – ShiS Jul 18 '20 at 22:53
0

I'd phrase it more directly:

comment = "<!--" > *(qi::char_ - "--") > "-->";

Remember to make the rule lexeme (disable/ignore skipper). (See Boost spirit skipper issues)

#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
using It = std::string::const_iterator;

int main() {
    qi::rule<It> comment; // lexeme
    comment = "<!--" > *(qi::char_ - "--") > "-->";
}
sehe
  • 374,641
  • 47
  • 450
  • 633
  • My final test code example is: `namespace qi = boost::spirit::qi; std::string s = ""; std::string::const_iterator f = s.cbegin(); bool r = qi::phrase_parse(f, s.cend(), qi::lexeme[""], qi::space);` 1. I've used sequence (>>) instead of expectation (>) parser, otherwise exception handling must be used. 2. I've wrapped whole expression into `lexeme[]`, otherwise loosing the fist space after " – ShiS Jul 18 '20 at 23:15
  • First off, comments are not suited for code. See [here instead](http://coliru.stacked-crooked.com/a/63d4b5f6b1b5df7f). – sehe Jul 18 '20 at 23:22
  • 1. that's your option. However, keep in mind it *is* by definition invalid XML, so you may want to prevent back-tracking the grammar (which is why expectation points exist). – sehe Jul 18 '20 at 23:22
  • 2. Good eye for detail. That was also correct in my rule, which doesn't even declare a skipper. Note that my [counter-offer](http://coliru.stacked-crooked.com/a/63d4b5f6b1b5df7f) simplifies by not even using a skipper as well. This is why I [linked to the other answer](https://stackoverflow.com/questions/17072987/boost-spirit-skipper-issues/17073965#17073965) for backgrounds. – sehe Jul 18 '20 at 23:23
  • 3. You may need better eye for detail, though: [because your modification doesn't do what you think it does](http://coliru.stacked-crooked.com/a/4d4370bed585e597). That's because `a = qi::char_(".....")` is a **charset**, and so is `~a` (see [docs](https://www.boost.org/doc/libs/1_73_0/libs/spirit/doc/html/spirit/qi/reference/char/char.html#spirit.qi.reference.char.char.expression_semantics)). You **need** a literat "--" match. See my original answer, [reflected here](http://coliru.stacked-crooked.com/a/2429abdca8f1ba19). #cheers – sehe Jul 18 '20 at 23:28