Qual è il problema con questo semplice boost :: :: spirito parser qi?
-
01-10-2019 - |
Domanda
Ho questo semplice parser lo scopo di analizzare stile VB corde doppie virgolette. Così, il parser dovrebbe girare qualcosa come
"This is a quoted string containing quotes ("" "")"
in una potenza di
This is a quoted string containing quotes (" ")
Questa è la grammatica sono arrivato fino a questo:
namespace qi = boost::spirit::qi;
namespace wide = qi::standard_wide;
class ConfigurationParser : public qi::grammar<std::wstring::iterator, std::wstring()>
{
qi::rule<std::wstring::iterator, std::wstring()> quotedString;
qi::rule<std::wstring::iterator> doubleQuote;
public:
ConfigurationParser() : ConfigurationParser::base_type(quotedString, "vFind Command Line")
{
doubleQuote = (wide::char_(L'"') >> wide::char_(L'"'));
quotedString = L'"' >> +(doubleQuote[qi::_val = L'"'] | (wide::char_ - L'"'))>> L'"';
}
};
Tuttavia, l'attributo sto ottenendo è un marchio singolo apice ( "), piuttosto che il messaggio analizzata completo.
Soluzione
È possibile farlo senza azioni semantiche:
class ConfigurationParser
: public qi::grammar<std::wstring::iterator, std::wstring()>
{
qi::rule<std::wstring::iterator, std::wstring()> quotedString;
qi::rule<std::wstring::iterator, wchar_t()> doubleQuote;
public:
ConfigurationParser()
: ConfigurationParser::base_type(quotedString, "vFind Command Line")
{
doubleQuote = wide::char_(L'"') >> omit[wide::char_(L'"')];
quotedString = L'"' >> +(doubleQuote | (wide::char_ - L'"')) >> L'"';
}
};
La direttiva omit[]
esegue ancora il parser incorporato, ma non espone qualsiasi attributo, rendendo la regola doubleQuote restituire un singolo L'"'
.
Altri suggerimenti
Credo che non lo fai salvare il risultato corretto:
doubleQuote[qi::_val = L'"']
Qui, a causa del segno '=', si ignora ciò che era già in. Provate con '+ =' invece.
doubleQuote[qi::_val += L'"']
Inoltre, non so se il risparmio è automatico, potrebbe essere necessario aggiungere lo stesso '+ =' dopo l'altro parser in subordine:
(wide::char_ - L'"')[qi::_val += boost::spirit::arg_names::_1]
Ma io non sono che il bene con Qi quindi forse è automatizzato, che avrebbe senso.
Beh, io non sono del tutto sicuro perché, ma sono stato in grado di risolvere il problema spostando l'azione assegnazione in regola sotto:
doubleQuote %= (wide::char_(L'"') >> L'"')[qi::_val = L'"'];
doubleQuote.name("double quote");
quotedString = L'"' >> +(doubleQuote | (wide::char_ - L'"')) >> L'"';
quotedString.name("quoted string");
Si noti l'uso di operator %=
per doubleQuote e il fatto che l'azione semantica si trova ora là.