4

I have a grammar similar to the following:

ruleFormat %= ruleComment | ruleSpec;
ruleFile %= ruleFormat % ruleNewline;

And rules are so declared:

rule<Iterator, void()> ruleComment;
rule<Iterator, int()> ruleSpec, ruleFormat;
rule<Iterator, std::vector<int>()> ruleFile;

(I am not actually using int, but a structure with some ints in it).

Well, the grammar seems to work properly: when ruleSpec matches an integer, the rule has that attribute which is in turn given to the vector.

The problem is when ruleComment matches in ruleFormat, because the data is set to be null, and a null value is placed inside the vector. The result is that the vector is filled with a mix of "right" values and "wrong" zeroes.

How can I prevent this from happening?

EDIT: as requested, here a sample code:

template <typename Iterator>
struct MyGrammar: public qi::grammar<Iterator, std::vector<int>()> {
    MyGrammar(): MyGrammar::base_type(ruleFile) {
        ruleComment = qi::lit('@');
        ruleSpec %= qi::int_;

        ruleFormat %= ruleComment | ruleSpec;
        ruleFile %= ruleFormat % ' ';

        ruleComment.name("COMMENT");
        ruleSpec.name("SPEC");
        ruleFormat.name("FORMAT");
        ruleFile.name("FILE");

        qi::debug(ruleComment);
        qi::debug(ruleSpec);
        qi::debug(ruleFormat);
        qi::debug(ruleFile);
    }
    qi::rule<Iterator, void()> ruleComment;
    qi::rule<Iterator, int()> ruleSpec, ruleFormat;
    qi::rule<Iterator, std::vector<int>()> ruleFile;
};

int main() {
    typedef std::string::const_iterator Iter;
    std::string subj = "0 @ @ 12 3 @ 4 @ 56 @ ";

    MyGrammar<Iter> gram;
    qi::parse(subj.cbegin(), subj.cend(), gram);
    return 0;
}

From the debug information, I am getting:

<attributes>[[0, 0, 0, 12, 3, 0, 4, 0, 56, 0]]</attributes>

while I'd like to obtain is avoid to place 0 in the vector when @ matches

<attributes>[[0, 12, 3, 4, 56]]</attributes>
AkiRoss
  • 11,745
  • 6
  • 59
  • 86

0 Answers0