Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在Boost.Spirit中解析短语开头之前的结尾_C++_Boost_Boost Spirit_Boost Spirit Qi - Fatal编程技术网

C++ 在Boost.Spirit中解析短语开头之前的结尾

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解析@前面

我正试图让Boost.Spirit解析MSVC损坏的符号。这些措施的形式如下:


?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'