SQL 構文の独自の拡張機能をトークン化したいと考えています。これには、二重引用符で囲まれた文字列内のエスケープされた二重引用符の認識が含まれます。たとえば、MySQL では、これら 2 つの文字列トークンは同等です: """"
(2 番目の二重引用符はエスケープ文字として機能します) と'"'
. さまざまなことを試しましたが、トークンの値を置き換える方法に行き詰まっています。
#include <boost/spirit/include/lex_lexertl.hpp>
namespace lex = boost::spirit::lex;
template <typename Lexer>
struct sql_tokens : lex::lexer<Lexer>
{
sql_tokens()
{
string_quote_double = "\\\""; // '"'
this->self("INITIAL")
= string_quote_double [ lex::_state = "STRING_DOUBLE" ] // how to also ignore + ctx.more()?
| ...
;
this->self("STRING_DOUBLE")
= lex::token_def<>("[^\\\"]*") // action: ignore + ctx.more()
| lex::token_def<>("\\\"\\\"") // how to set token value to '"' ?
| lex::token_def<>("\\\"") [ lex::_state = "INITIAL" ]
;
}
lex::token_def<> string_quote_double, ...;
};
トークンが見つかった"
ときにトークンの値を設定するにはどうすればよいでしょうか。""
それとは別に、次の質問もあります: ctx.more() を呼び出すセマンティック アクションのファンクターを記述し、同時にトークンを無視することができます (したがって、「低レベル」トークンを「高レベル」文字列トークンに結合します) )。しかし、これを lex::_state = ".." とエレガントに組み合わせる方法は?