В чем проблема с этим простым анализатором boost :: spirit :: qi? - PullRequest
1 голос
/ 30 июня 2010

У меня есть этот простой парсер, предназначенный для анализа строк в двойных кавычках в стиле VB.Таким образом, синтаксический анализатор должен превратить что-то вроде

"This is a quoted string containing quotes ("" "")"

в вывод

This is a quoted string containing quotes (" ")

Вот грамматика, с которой я пришел для этого:Однако атрибут, который я получаю, - это знак одинарной кавычки ("), а не полное проанализированное сообщение.

Ответы [ 3 ]

4 голосов
/ 30 июня 2010

Вы можете сделать это без каких-либо семантических действий:

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'"'; 
    } 
}; 

Директива omit[] по-прежнему выполняет встроенный синтаксический анализатор, но не предоставляет никаких атрибутов, поэтому правило doubleQuote возвращает один L'"'.

1 голос
/ 30 июня 2010

Ну, я не совсем уверен, почему, но я смог это исправить, переместив действие назначения в подчиненное правило:

doubleQuote %= (wide::char_(L'"') >> L'"')[qi::_val = L'"'];
doubleQuote.name("double quote");

quotedString = L'"' >> +(doubleQuote | (wide::char_ - L'"')) >> L'"';
quotedString.name("quoted string");

Обратите внимание на использование operator %= для doubleQuote иДело в том, что семантическое действие теперь находится там.

1 голос
/ 30 июня 2010

Я думаю, вы не сохраните результат должным образом:

doubleQuote[qi::_val = L'"']

Здесь, из-за знака «=», вы переопределяете то, что уже было. Попробуйте вместо него «+ =».

doubleQuote[qi::_val += L'"']

Кроме того, я не знаю, является ли сохранение автоматическим, возможно, вам придется добавить тот же '+ =' после другого парсера в альтернативе:

(wide::char_ - L'"')[qi::_val += boost::spirit::arg_names::_1]

Но я не так хорош с Ци, так что, возможно, он автоматизирован, что имело бы смысл.

...