Разбор сбежавших строк с буст-духом - PullRequest
5 голосов
/ 27 октября 2010

Я работаю с Spirit 2.4 и хотел бы проанализировать структуру, подобную этой:

Text {text_field};

Дело в том, что в text_field есть экранированная строка с символами '{', '}' и '\'.Я хотел бы создать парсер для этого с помощью ци.Я пытался это:

using boost::spirit::standard::char_;
using boost::spirit::standard::string;
using qi::lexeme;
using qi::lit;

qi::rule< IteratorT, std::string(), ascii::space_type > text;
qi::rule< IteratorT, std::string(), ascii::space_type > content;
qi::rule< IteratorT, std::string(), ascii::space_type > escChar;


text %= 
  lit( "Text" ) >> '{' >>
    content >>
  "};"
  ;

content %= lexeme[ +( +(char_ - ( lit( '\\' ) | '}' ) )  >> escChar ) ];

escChar %= string( "\\\\" ) 
  | string( "\\{" ) 
  | string( "\\}" );

Но даже не компилируется.Есть идеи?

1 Ответ

8 голосов
/ 27 октября 2010

Ваша грамматика может быть записана как:

qi::rule< IteratorT, std::string(), ascii::space_type > text; 
qi::rule< IteratorT, std::string() > content;   
qi::rule< IteratorT, char() > escChar;   

text = "Text{" >> content >> "};";  
content = +(~char_('}') | escChar); 
escChar = '\\' >> char_("\\{}");

т.е.

  • текст равен Text{, за которым следует содержимое, за которым следует }

  • содержимое является хотя бы одним экземпляром либо символ (но не }), либо EscChar

  • escChar - одиночный экранированный \\, { или }

Обратите внимание, что правило escChar теперь возвращает один символ и отбрасывает экранирующий \\. Я не уверен, что это то, что вам нужно. Кроме того, я удалил шкипер для правил content и escChar , которые позволяют исключить lexeme[] (правило без шкипера действует как неявная лексема).

...