2

I need to parse an expression and I'm using boost :: spirit, the expression must have the form (@anything but @ followed of the string .PV@), and I am using the following grammar

P = S >> "." >> V;

S = ch_p('@') >> +~ch_p('@');

V = str_p(".PV@");

but does not work me, could you tell me where is the error. I need do it with a grammar and I am using namespace boost::spirit

sehe
  • 374,641
  • 47
  • 450
  • 633
  • You're using ancient SpiritV1. Please move to SpiritV2. Also, your description is very very confusing. Can you give a SSCCE with expected input/outputs? – sehe Jan 26 '14 at 19:51
  • What is your use case? This sounds like something you could do with a regular expression. – olleicua Jan 26 '14 at 19:53

1 Answers1

2

Update For completeness adding the regex approach (see at the bottom)

In spirit V2 I'd suggest the simpler

    P = S >> V;
    S = '@' >> +(char_ - '@' - V);
    V = ".PV@";

Assuming that you didn't mean a double . to be required. See a test program Live On Coliru.

Also, note the confix parser in the spirit repository, which could do this slightly more succinctly:

confix('@', ".PV@")[+(char_ - '@' - ".PV@")]

See that Live On Coliru as well.

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/repository/include/qi_confix.hpp>

namespace qi = boost::spirit::qi;
using boost::spirit::repository::confix;

int main()
{
    std::string const input("@anything but &at; followed of the string .PV@");
    std::string parsed;

    auto f(input.begin()), l(input.end());
    bool ok = qi::parse(
            f, l,
            confix('@', ".PV@") [+(qi::char_ - '@' - ".PV@")],
            parsed);

    if (ok)   std::cout << "parse success\ndata: " << parsed           << "\n";
    else      std::cerr << "parse failed: '"       << std::string(f,l) << "'\n";
    if (f!=l) std::cerr << "trailing unparsed: '"  << std::string(f,l) << "'\n";

    return ok? 0 : 255;
}

Output:

parse success
data: anything but &at; followed of the string

Regex Approach

Depending on your use case, you could use a regular expression as has been pointed out in comments. See a simple demo Live On Coliru

#include <boost/regex.hpp>
using boost::regex;

int main()
{
    std::string const input("@anything but &at; followed of the string .PV@");

    boost::smatch matches;
    if(regex_search(input, matches, regex("@(.*?)\\.PV@")))
        std::cout << "Parse success, match string: '" << matches[1] << "'\n";
}

Bear in mind,

  • Boost Regex is not header only, so you incur the library dependency if you don't already use it
  • std::regex is not ready on any compiler/platform I know of
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Added the [regex approach](http://coliru.stacked-crooked.com/a/c4b590b47dde47cd) for the sake of completeness – sehe Jan 26 '14 at 21:37
  • 1
    I believe GCC 4.8.2 libstdc++ now has a regex implementation, libc++ has had it since forever, and MSVC also had it since at least VS2008 (in tr1 back then), and in `std` since 2010? How is it not ready? (I haven't used any of these myself for anything, I just know of their existence) – rubenvb Jan 26 '14 at 21:40
  • @rubenvb Last time I checked they all "appeared" to have ``, but it was utterly broken. Now, I haven't included libc++ there. Also, this is quite widespread knowledge, so I'm pretty sure I can't be far off. Then again, perhaps recent versions all of a sudden came up with the goods, but chances are the OP isn't using them, so the fair warning stands. – sehe Jan 26 '14 at 21:43
  • [this answer](http://stackoverflow.com/a/12665408/85371) (with a handsome +50 votes) mentions that GCC 4.9 will ship with working `std::regex`. It's unknown when this will be released http://gcc.gnu.org/develop.html#timeline – sehe Jan 26 '14 at 21:59