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
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