- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试让 Boost.Spirit 解析 MSVC 损坏的符号。这些采取的形式:
这意味着“volatile int myclass::myvolatileStaticMember”。
?myvolatileStaticMember@myclass@@2HC
解析的“关键”是双符号“@@”。 @@ 之前是符号的名称,它由一个 C++ 标识符和后跟零个或多个“@”的附加标识符组成,以在其绝对命名空间层次结构中完全表示该符号。 @@ 之后是标识符的说明(变量、函数等)
现在,我可以让 Boost.Spirit 解析 @@ 之前的部分或 @@ 之后的部分。我还没有想出如何让 Boost.Spirit 找到 @@ 并将它之前的内容提供给一个自定义解析器,并将它之后的内容提供给另一个自定义解析器。
这是我对 @@ 之前部分的解析器:
// This grammar is for a MSVC mangled identifier
template<typename iterator> struct msvc_name : grammar<iterator, SymbolType(), locals<SymbolType, string>>
{
SymbolTypeDict &typedict;
void name_writer(SymbolType &val, const string &i) const { val.name=i; }
void dependent_writer(SymbolType &val, const string &i) const
{
SymbolTypeDict::const_iterator dt=typedict.find(i);
if(dt==typedict.end())
{
auto _dt=typedict.emplace(make_pair(i, SymbolType(SymbolTypeQualifier::None, SymbolTypeType::Namespace, i)));
dt=_dt.first;
}
val.dependents.push_back(&dt->second);
}
// These work by spreading the building of a templated type over multiple calls using local variables _a and _b
// We accumulate template parameters into _a and accumulate mangled symbolness into _b
void begin_template_dependent_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(SymbolType &a, string &b, long long constant) const
{
string i("_c"+to_string(constant));
SymbolTypeDict::const_iterator dt=typedict.find(i);
if(dt==typedict.end())
{
auto _dt=typedict.emplace(make_pair(i, SymbolType(SymbolTypeQualifier::None, SymbolTypeType::Constant, to_string(constant))));
dt=_dt.first;
}
a.templ_params.push_back(&dt->second);
b.append(i);
}
void add_template_type_dependent_writer(SymbolType &a, string &b, SymbolTypeType type) const
{
string i("_t"+to_string(static_cast<int>(type)));
SymbolTypeDict::const_iterator dt=typedict.find(i);
if(dt==typedict.end())
{
auto _dt=typedict.emplace(make_pair(i, SymbolType(SymbolTypeQualifier::None, type)));
dt=_dt.first;
}
a.templ_params.push_back(&dt->second);
b.append(i);
}
void finish_template_dependent_writer(SymbolType &val, SymbolType &a, string &b) const
{
SymbolTypeDict::const_iterator dt=typedict.find(b);
if(dt==typedict.end())
{
auto _dt=typedict.emplace(make_pair(b, a));
dt=_dt.first;
}
val.dependents.push_back(&dt->second);
}
msvc_name(SymbolTypeDict &_typedict) : msvc_name::base_type(start), typedict(_typedict)
{
identifier=+(char_ - '@');
identifier.name("identifier");
template_dependent_identifier=+(char_ - '@');
template_dependent_identifier.name("template_dependent_identifier");
dependent_identifier=+(char_ - '@');
dependent_identifier.name("dependent_identifier");
start = identifier [ boost::phoenix::bind(&msvc_name::name_writer, this, _val, _1) ] >> *(
lit("@@") >> eps
| (("@?$" > template_dependent_identifier [ boost::phoenix::bind(&msvc_name::begin_template_dependent_writer, this, _val, _a, _b, _1) ])
> "@" > +(( "$0" > constant [ boost::phoenix::bind(&msvc_name::add_template_constant_dependent_writer, this, _a, _b, _1) ])
| type [ boost::phoenix::bind(&msvc_name::add_template_type_dependent_writer, this, _a, _b, _1) ])
>> eps [ boost::phoenix::bind(&msvc_name::finish_template_dependent_writer, this, _val, _a, _b) ])
| ("@" > dependent_identifier [ boost::phoenix::bind(&msvc_name::dependent_writer, this, _val, _1) ]))
;
BOOST_SPIRIT_DEBUG_NODE(start);
start.name("msvc_name");
on_error<boost::spirit::qi::fail, iterator>(start,
cerr << boost::phoenix::val("Parsing error: Expected ") << _4 << boost::phoenix::val(" here: \"")
<< boost::phoenix::construct<string>(_3, _2) << boost::phoenix::val("\"") << endl);
}
rule<iterator, SymbolType(), locals<SymbolType, string>> start;
rule<iterator, string()> identifier, template_dependent_identifier, dependent_identifier;
msvc_type type;
msvc_constant<iterator> constant;
};
您会注意到“lit("@@") >> eps”,我试图让它在看到 @@ 后停止匹配。现在这里是应该匹配一个完整的错位符号的部分:
template<typename iterator> struct msvc_symbol : grammar<iterator, SymbolType()>
{
SymbolTypeDict &typedict;
/* The key to Microsoft symbol mangles is the operator '@@' which consists of a preamble
and a postamble. Immediately following the '@@' operator is:
Variable:
3<type><storage class>
Static member variable:
2<type><storage class>
Function:
<near|far><calling conv>[<stor ret>] <return type>[<parameter type>...]<term>Z
<Y |Z ><A|E|G >[<?A|?B|?C|?D>]<MangledToSymbolTypeType...> <@>Z
Member Function:
<protection>[<const>]<calling conv>[<stor ret>] <return type>[<parameter type>...]<term>Z
<A-V >[<A-D> ]<A|E|G >[<?A|?B|?C|?D>]<MangledToSymbolTypeType...> <@>Z
*/
msvc_symbol(SymbolTypeDict &_typedict) : msvc_symbol::base_type(start), typedict(_typedict), name(_typedict), variable(_typedict)
{
start="?" >> name >> ("@@" >> variable);
BOOST_SPIRIT_DEBUG_NODE(start);
on_error<boost::spirit::qi::fail, iterator>(start,
cerr << boost::phoenix::val("Parsing error: Expected ") << _4 << boost::phoenix::val(" here: \"")
<< boost::phoenix::construct<string>(_3, _2) << boost::phoenix::val("\"") << endl);
}
rule<iterator, SymbolType()> start;
msvc_name<iterator> name;
msvc_variable<iterator> variable;
};
所以,它匹配“?”很容易;)。问题是它在“?”之后发送所有内容。到 msvc_name 解析器,所以不是从 @@ 开始的位进入 msvc_variable,其余部分进入 msvc_name,msvc_name 消耗所有直到并包括 @@。这不直观,因为人们会认为括号意味着先做那件事。
因此,如果我更换:
和
开始=? >> 名称 >> ("@@">> 变量);
...一切正常。
开始=? >> 名称 >> 变量;
但是我真的不想这样做。理想情况下,我希望 Boost.Spirit 在 msvc_symbol 中在 @@ 处干净地拆分,并按原样“做正确的事”。我在想我可能没有足够的递归思考?无论哪种方式,我都很难过。
注意:是的,我知道我可以在@@ 处断开字符串并运行两个单独的解析器。这不是我要问的 - 相反,我是在问如何配置 Boost.Spirit 以在开始之前解析短语的结尾。
另请注意:我知道 skipper 可以用来制作@@ 空格并以这种方式进行拆分。问题是@@ 之前的内容非常具体,@@ 之后的内容也是如此。因此它不是真正的空白。
非常感谢任何可以提供帮助的人。从谷歌和 Stackoverflow 上搜索与此相关的问题,克服 Boost.Spirit 的“从左到右的贪婪”是很多人的问题。
尼尔
最佳答案
看起来你可以做很多事情:
明确禁止在您希望使用“@”的地方使用双“@@”。另见
先标记化(使用 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";
}
}
输出:
Qualified name: myclass::myvolatileStaticMember
Type indication: '2HC'
关于c++ - 在 Boost.Spirit 中解析短语开头之前的结尾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13712671/
我们正在使用一个脚本,它会返回以下内容120007CONSULTA DE DEUDA CORRECTA.01TEST我正在尝试从awk中获得 CONSULTA DE DEUDA CORRECTA 的短
我正在使用以下查询: { "_source": [ "title", "bench", "id_", "court",
例如,我有数十亿个短语,我想要将相似的短语聚集在一起。 > strings.to.cluster <- c("Best Toyota dealer in bay area. Drive out wit
我有一个包含大约 1000 个关键字/短语(一到四个字长)的数据库表 - 这个表很少更改,所以我可以将数据提取到更有用的东西中(比如正则表达式?) - 所以这没有找到/基于自然语言处理猜测关键词..
我想确保我从一开始就做对了,但我找不到好的答案,所以我想问一下。 我要做的是以下内容。 以一句话为例:The quick brown fox jumped over the lazy dog"并使用全
我有一个表单,其中有两个单选按钮。 应该从字符串中搜索整个字符串,第二个应该搜索至少一个单词。 例如: 我将搜索“Awesome ideas for startup”。 如果我选中“搜索整个字符串/短
我有... 一组固定关键字和词组(大约 1,000,000 个),例如 birthday、happy new year、vacation等 10 到 500 字之间的一些可变文本。 我想…… 识别文本
有没有办法删除字符串中重复的和连续的单词/短语?例如。 [in]: foo foo bar bar foo bar [out]: foo bar foo bar 我试过这个: >>> s = 'thi
我正在寻找一种在文本中搜索短语或惯用表达的方法,无论时态或可能的介词/副词如何,例如如果我正在寻找 call off我还想找到 My boss called the meeting off. 之类的用
PowerShell 有一些语法特性,我找不到太多相关文档。今天我的问题是 ? {...} 例子 PS> Get-SPServiceInstance | ? {$_.GetType.toString(
我通过 PHP 使用 Solr 来搜索我网站的各个方面。我正在尝试实现一项功能,但找不到任何有关如何实现它的信息。 我有一组文档(评论),每个文档都与特定产品有关。 我想找到出现在单个产品的多条评论中
我正在从事自然语言生成任务,需要检索与 Cyc 术语等效的自然语言单词或短语。例如。 “#$EatingEvent”->“吃”或“#$Coyote-Animal”->“土狼”。 如何通过 Java A
我在使用 Java 中的以下正则表达式时遇到问题。我删除了双引号,以使其更具可读性。由于缺乏更好的词,我还将每个“组件”放在单独的行上(但实际的表达式会将行合并,行之间没有空格): (?:\bIN(?
我有一个 MySQL 数据库,我正在尝试使用 PHP 获取趋势主题(流行短语或单词)。我尝试了一些查询,但似乎没有什么对我有用。 最佳答案 您可以尝试创建一个包含两列的新表:WORD 和 COUNT,
我在 MySql 中有一个包含城市的表。 |---------------------|------------------| | ID | City
我正在处理搜索页面上的用户输入。如果用户选择“所有单词”类型的搜索,那么我会从搜索文本中删除所有 bool 搜索运算符,并在每个真实单词之间添加 ' AND '。在大多数情况下非常简单。但是,我不知道
我使用的语音识别软件给出的结果不是最佳的。 例如:session 返回为 fashion 或 mission。 现在我有一本像这样的字典: matches = { 'session': ['fas
我厌倦了使用 Gimp 无休止地滚动所有字体来不规律地搜索完美字体,所以我想:“为什么不为每种字体构建一个可视的 pangrams 列表”。 因此,我尝试构建一个 php 脚本,该脚本在 .fonts
如何编写一个 RegEx 模式来测试一个字符串是否包含多个具有以下结构的子字符串: "cake.xxx" xxx 是任何东西,但不是“奶酪”、“牛奶”或“黄油”。 例如: “我有一个 cake.hon
我有一个字段“部门”,它是一个列表:{“部门”:[“餐饮服务”,“软件开发”,“制造”,“部署”]}' 我想聚合“部门”中以“d”开头的元素。即,从所有记录进行部署。 我能够找到包含一个前缀为“d”但
我是一名优秀的程序员,十分优秀!