I have to parse the following piece of text
Camera {
position 0 0 0
direction 0 -1 0
up 0 1 0
FOVy 45
}
My choice went on boost:spirit since I had not to deal with flex or bison.
I finally had this grammar
struct camera_grammar : qi::grammar<Iterator, camera(), ascii::space_type>
{
qi::rule<Iterator, camera(), ascii::space_type> start;
camera_grammar() : camera_grammar::base_type(start)
{
start %=
lit("Camera")
>> '{'
>> (lit("position") >> float_ >> float_ >> float_)
>> (lit("direction") >> float_ >> float_ >> float_)
>> (lit("up") >> float_ >> float_ >> float_)
>> (lit("FOVy") >> int_)
>> '}'
;
}
};
The problem is that the parts inside the curly braces could even be swapped; I have read about the permutation operator ^ but I read that matches when at least one of the operands is matched in any order. I need my grammar to match only when there are all of them in any order and once only.
Can somebody help me?
Hartmut Kaiser explains how to do this in this article.
You'll want to define the no_empties_impl
class as described in the article, and then declare a function
phoenix::function<no_empties_impl> const no_empties = no_empties_impl();
Then, in your grammar, you'll want to define rules for each of position
, direction
, up
, and FOVy
. Then your start grammar will look like (untested):
start %=
lit("Camera")
>> '{'
>> position ^ direction ^ up ^ FOVy
>> '}'
[qi::_pass = no_empties(qi::_0)]
;