C++ 在Boost.Spirit中解析短语开头之前的结尾
我正试图让Boost.Spirit解析MSVC损坏的符号。这些措施的形式如下:C++ 在Boost.Spirit中解析短语开头之前的结尾,c++,boost,boost-spirit,boost-spirit-qi,C++,Boost,Boost Spirit,Boost Spirit Qi,我正试图让Boost.Spirit解析MSVC损坏的符号。这些措施的形式如下: ?myvolatileStaticMember@myclass@@2HC 这意味着“volatile int myclass::myvolatileStaticMember” 解析的“键”是双精度at符号“@”。在@之前,符号是由C++标识符组成的,后面跟着零或更多的“@”附加标识符,以完全表示其绝对命名空间层次结构中的符号。在@之后是标识符的说明(变量、函数等) 现在,我可以让Boost.Spirit解析@前面
?myvolatileStaticMember@myclass@@2HC
这意味着“volatile int myclass::myvolatileStaticMember”
解析的“键”是双精度at符号“@”。在@之前,符号是由C++标识符组成的,后面跟着零或更多的“@”附加标识符,以完全表示其绝对命名空间层次结构中的符号。在@之后是标识符的说明(变量、函数等)
现在,我可以让Boost.Spirit解析@前面的部分或@后面的部分。我还没有弄清楚如何获得Boost.Spirit来找到@并将它之前的内容提供给一个自定义解析器,之后的内容提供给另一个自定义解析器
这是我对@@@前面部分的解析器:
//此语法用于MSVC损坏的标识符
模板结构msvc_名称:语法
{
SymbolTypeDict&typedict;
void name_writer(SymbolType&val,const string&i)const{val.name=i;}
无效相关写入程序(SymbolType和val、常量字符串和i)常量
{
SymbolTypeDict::const_迭代器dt=typedict.find(i);
如果(dt==typedict.end())
{
auto _dt=typedict.emplace(生成一对(i,SymbolType(SymbolTypeQualifier::None,SymbolTypeType::Namespace,i));
dt=_dt.first;
}
val.dependents.push_back(&dt->second);
}
//它们通过使用局部变量a和b将模板类型的构建扩展到多个调用来工作
//我们将模板参数累积到_a中,将损坏的符号累积到_b中
void begin\u template\u dependent\u writer(SymbolType&,SymbolType&a,string&b,const string&i)const
{
a=SymbolType(SymbolTypeQualifier::None,SymbolTypeType::Class,i);
b=i;
}
void add_template_constant_dependent_writer(符号类型a、字符串b、长常量)常量
{
字符串i(“_c”+到_字符串(常量));
SymbolTypeDict::const_迭代器dt=typedict.find(i);
如果(dt==typedict.end())
{
auto _dt=typedict.emplace(生成一对(i,SymbolType(SymbolTypeQualifier::None,SymbolTypeType::Constant,to_字符串(Constant)));
dt=_dt.first;
}
a、 模板参数向后推(&dt->second);
b、 附加(i);
}
void add_template_type_dependent_writer(SymbolType&a、string&b、SymbolTypeType类型)常量
{
字符串i(“_t”+to_string(static_cast(type)));
SymbolTypeDict::const_迭代器dt=typedict.find(i);
如果(dt==typedict.end())
{
auto _dt=typedict.emplace(生成一对(i,SymbolType(SymbolTypeQualifier::None,type));
dt=_dt.first;
}
a、 模板参数向后推(&dt->second);
b、 附加(i);
}
无效完成\模板\依赖\写入程序(SymbolType&val、SymbolType&a、字符串&b)常量
{
SymbolTypeDict::const_迭代器dt=typedict.find(b);
如果(dt==typedict.end())
{
auto _dt=typedict.emplace(生成一对(b,a));
dt=_dt.first;
}
val.dependents.push_back(&dt->second);
}
msvc_名称(SymbolTypeDict&_typedict):msvc_名称::基本类型(开始),typedict(_typedict)
{
标识符=+(字符-@');
标识符。名称(“标识符”);
模板依赖标识符=+(字符-'@');
模板依赖标识符。名称(“模板依赖标识符”);
从属_标识符=+(char_-'@');
从属_标识符。名称(“从属_标识符”);
start=identifier[boost::phoenix::bind(&msvc_name::name_writer,this,_val,_1)]>>*(
照明(“@”)>>eps
|((“@?$”>模板依赖的\u标识符[boost::phoenix::bind(&msvc\u name::begin\u模板依赖的\u writer,this,\u val,\u a,\u b,\u 1)])
>“@”>+(($0“>constant[boost::phoenix::bind(&msvc_name::add_template_constant_dependent_writer,this,_a,_b,_1)])
|类型[boost::phoenix::bind(&msvc\u name::add\u template\u type\u dependent\u writer,this,\u a,\u b,\u 1)])
>>eps[boost::phoenix::bind(&msvc_name::finish_template_dependent_writer,this,_val,_a,_b)])
|(“@”>dependent_标识符[boost::phoenix::bind(&msvc_name::dependent_writer,this,_val,_1)])
;
启动调试节点(启动);
开始名称(“msvc_名称”);
on_错误(开始,
cerr看起来你可以做很多事情:
明确禁止在期望“@”的地方使用双“@”。另请参见
首先标记化(使用Spirit Lex?)
这里我向您展示了第一种方法的一个工作示例:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
namespace qi = boost::spirit::qi;
template<typename T> T reversed(T c) { return T(c.rbegin(), c.rend()); }
int main (int argc, char** argv)
{
const std::string input("?myvolatileStaticMember@myclass@@2HC");
auto f = begin(input), l = end(input);
auto identifier = +~qi::char_("@");
auto delimit = qi::lit("@") - "@@";
std::vector<std::string> qualifiedName;
std::string typeId;
if (qi::parse(f,l,
'?' >> identifier % delimit >> "@@" >> +qi::char_,
qualifiedName,
typeId))
{
using namespace boost::spirit::karma;
qualifiedName = reversed(qualifiedName);
std::cout << "Qualified name: " << format(auto_ % "::" << "\n", qualifiedName);
std::cout << "Type indication: '" << typeId << "'\n";
}
}
太棒了!流血的事情显而易见——正如我慢慢开始摸索的那样,Boost Spirit确实总是从左到右解析,所以“@”>identifier”将匹配@,如果标识符不匹配,则期望值将失败。因此,需要从“@”—“@”的角度来考虑作为比赛线。非常感谢你给我指出这一点。尼亚拉。我想我记得这一点
Qualified name: myclass::myvolatileStaticMember
Type indication: '2HC'