1

I have a curious case I'm working with right now, where the I need to use the same symbol table in two different contexts. In the case of a "J" command, I'd like to only look at elements of the symbol table that begin with a particular prefix, but this prefix is NOT to be specified in the parsed text, but only used for the lookup in the symbol table.

My current solution is to loop through the symbol table outside of the parser, generating a second symbol table exclusively for use for this "J" command, but I was curious if there was a way to combine this into the parser.

Currently, the following toy code results in 100,10,10 , is there a reasonably easy modification to the first symTable reference in myRule, such that it will parse as 100,10,1?

#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/qi_symbols.hpp>
#include <boost/foreach.hpp>
#include <string>
#include <vector>
#include <iostream>

namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;

int main() {
    qi::symbols<char, unsigned int> symTable;
    symTable.add("prefix_A", 1)
                ("A"       , 10);
    qi::rule<std::string::const_iterator, unsigned int()> xRule = qi::lit("X")[qi::_val = 100];
    qi::rule<std::string::const_iterator, unsigned int()> myRule =
                      (qi::lit("J") >> qi::omit[+qi::space] >> symTable/*("prefix_")*/)
                    | (qi::lit("R") >> qi::omit[+qi::space] >> symTable)
                    | xRule;

    std::string test = "X;R A;J A";
    std::string::const_iterator it= test.begin();
    std::string::const_iterator end= test.end();
    std::vector<unsigned int> results;

    if (!qi::parse(it, end, (myRule % ";"), results))
        std::cout << "Parse Failed\n";
    else {
        BOOST_FOREACH(unsigned int x, results)
            std::cout << x << ",";
        if(it != end)
            std::cout << "\nIncomplete Parse\n";
        else
            std::cout << "\nParsed\n";
    }
    return 0;
}
jkerian
  • 16,497
  • 3
  • 46
  • 59

0 Answers0