[spirit] parsing keyword or identifier
HI all - I have what I think is a simple problem: I'm trying to parse IES files, and there is a line that can have three options: TILT=NONE -or- TILT=INCLUDE -or- TILT=<filename> The way I'm trying to parse this line is: // in the case of TILT=INCLUDE or TILT=<filename> int lampToLuminaireGeom; int numPairsWithMulFactors = 0; std::string tiltFileName; BOOST_AUTO(keywordSym, (qi::lit("NONE") | qi::lit("INCLUDE"))); BOOST_AUTO(fileName, *char_ - keywordSym); BOOST_AUTO(initial, ( "TILT" >> char_('=') >> ( "NONE" | ( "INCLUDE" >> int_[ref(lampToLuminaireGeom) = _1] >> int_[ref(numPairsWithMulFactors) = _1] ) | fileName[ref(tiltFileName)] ) ) ); if(!phrase_parse(first, last, initial, space)) { return IES_INVALID; } The code works with NONE or INCLUDE, but not with files. As far as I know, there are no real restrictions on the filenames. At this point, the code posted above can't even get simple file names, but really I think what is required is that I grab anything non-whitespace after the '=' until it reaches an EOL. Can anyone provide some insight about what I may be doing wrong? Thanks, Brian
I have what I think is a simple problem: I'm trying to parse IES files, and there is a line that can have three options:
TILT=NONE -or- TILT=INCLUDE -or- TILT=<filename>
The way I'm trying to parse this line is:
// in the case of TILT=INCLUDE or TILT=<filename> int lampToLuminaireGeom; int numPairsWithMulFactors = 0;
std::string tiltFileName;
BOOST_AUTO(keywordSym, (qi::lit("NONE") | qi::lit("INCLUDE"))); BOOST_AUTO(fileName, *char_ - keywordSym);
Spirit grammars are still C++ and still obey the default C++ operator preferences. Use this instead: BOOST_AUTO(fileName, *(char_ - keywordSym)); and it will work.
BOOST_AUTO(initial, ( "TILT" >> char_('=') >> ( "NONE" | ( "INCLUDE" >> int_[ref(lampToLuminaireGeom) = _1] >> int_[ref(numPairsWithMulFactors) = _1] ) | fileName[ref(tiltFileName)] ) ) );
if(!phrase_parse(first, last, initial, space)) { return IES_INVALID; }
The code works with NONE or INCLUDE, but not with files. As far as I know, there are no real restrictions on the filenames. At this point, the code posted above can't even get simple file names, but really I think what is required is that I grab anything non-whitespace after the '=' until it reaches an EOL.
Can anyone provide some insight about what I may be doing wrong?
HTH Regards Hartmut --------------- http://boost-spirit.com
On Mon, May 2, 2011 at 7:18 PM, Hartmut Kaiser
Spirit grammars are still C++ and still obey the default C++ operator preferences. Use this instead:
BOOST_AUTO(fileName, *(char_ - keywordSym));
and it will work.
Hi Hartmut - Thanks for the input. I had tried this precedence before, and during my mucking about I guess I forgot to put the parens back in. In any case, the above production still doesn't work, because it continues parsing until the end of the file... TILT=foobar 1 2... will eat everything. I'm not sure how to make it stop at the end of the line, because I'm using the space-eating parser, which seems to eat whitespace before checking the rules. Additionally, I'm having trouble getting the parsed value into a string. I can get the above example to work like this: BOOST_AUTO(fileName, *((char_ - keywordSym) - qi::digit))[ref(tiltFileName) = _1]); I used digit because I know that a digit will follow the filename, but if the filename contains a digit, of course this will fail. That's one problem. The other problem is that tiltFileName only contains 'r' after parsing. My hunch is that this is because the char_ parser parses one character at a time, so only the last one is there. I tried wrapping the production as (*((char_ - keywordSym)-qi::digit))[...], but now I can't get the code to compile. Any further ideas are much appreciated. Brian
participants (2)
-
Brian Budge
-
Hartmut Kaiser