提升精神解析目标C类语言
Boost spirit parsing objective-C like language
我正在尝试使用boost的精神来重新实现iPhone越狱开发中的徽标解析perl脚本。
输入的示例如下:
%hook SBLockScreenView
-(void)setCustomSlideToUnlockText:(id)arg1
{
arg1 = @"Changed the slider";
%orig(arg1);
}
%end
到目前为止,我有:
namespace logos
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
struct class_hook
{
std::string class_name;
std::string method_signature;
std::string method_body;
};
template <typename Iterator>
struct class_hook_parser : qi::grammar<Iterator, class_hook(), ascii::space_type>
{
class_hook_parser() : class_hook_parser::base_type(start)
{
using qi::int_;
using qi::lit;
using qi::on_error;
using qi::fail;
using qi::double_;
using qi::lexeme;
using ascii::char_;
hooked_class %= lexeme[+(char_("a-zA-Z") - '-')];
method_sig %= lexeme[+(char_) - '{'];
method_body %= lexeme[+(char_ - '}')];
start %=
lit("%hook")
>> hooked_class
>> method_sig
>> method_body
>> lit("%end")
;
on_error<fail>
(
start,
boost::phoenix::ref(std::cout) << "Something errored!" << std::endl);
}
qi::rule<Iterator, std::string(), ascii::space_type> hooked_class;
qi::rule<Iterator, std::string(), ascii::space_type> method_sig;
qi::rule<Iterator, std::string(), ascii::space_type> method_body;
qi::rule<Iterator, class_hook(), ascii::space_type> start;
};
}
BOOST_FUSION_ADAPT_STRUCT(logos::class_hook,
(std::string, class_name)
(std::string, method_signature)
(std::string, method_body))
typedef std::string::const_iterator iterator_type;
typedef logos::class_hook_parser<iterator_type> class_hook_parser;
using boost::spirit::ascii::space;
std::string::const_iterator
iter = std::begin(tweak_source_code),
end = std::end(tweak_source_code);
class_hook_parser g;
logos::class_hook emp;
bool r = phrase_parse(iter, end, g, space, emp);
if (r) {
std::cout << "Got: " << boost::fusion::as_vector(emp) << std::endl;
}
else std::cout << "Something isn't working" << std::endl;
但奇怪的是,这只打印出Something isn't working
消息,而不是on_fail回调。我在解析中的错误在哪里,我如何获得实际工作和信息丰富的解析错误消息?
你的意思是
+(char_ - '{')
而不是
+(char_) - '{'
而且,您可能要求正文以作为签名的一部分被拒绝的{
开头。这是我的固定版本:
hooked_class = +char_("a-zA-Z");
method_sig = +(char_ - '{');
method_body = '{' >> +(char_ - '}') >> '}';
笔记:
- 删除
- 船长也可以删除
lexeme[]
指令。 - 从"a-zA-Z"集合中拒绝
-
是没有用的(它不在其中...... -
method_sig
现在包括所有空格(包括尾随换行符) - 使用BOOST_SPIRIT_DEBUG来深入了解为什么你的语法以神秘的方式工作
另请参阅:提升精神船长问题
住在科里鲁
//#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace logos
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
struct class_hook
{
std::string class_name;
std::string method_signature;
std::string method_body;
};
template <typename Iterator>
struct class_hook_parser : qi::grammar<Iterator, class_hook(), ascii::space_type>
{
class_hook_parser() : class_hook_parser::base_type(start)
{
using qi::int_;
using qi::lit;
using qi::on_error;
using qi::fail;
using qi::double_;
using qi::lexeme;
using ascii::char_;
hooked_class = +char_("a-zA-Z");
method_sig = +(char_ - '{');
method_body = '{' >> +(char_ - '}') >> '}';
start = "%hook"
>> hooked_class
>> method_sig
>> method_body
>> "%end"
;
on_error<fail> (start,
boost::phoenix::ref(std::cout) << "Something erroredn"
);
BOOST_SPIRIT_DEBUG_NODES((hooked_class)(method_sig)(method_body)(start))
}
private:
qi::rule<Iterator, std::string()> hooked_class, method_sig, method_body;
qi::rule<Iterator, class_hook(), ascii::space_type> start;
};
}
BOOST_FUSION_ADAPT_STRUCT(logos::class_hook, class_name, method_signature, method_body)
int main() {
typedef std::string::const_iterator iterator_type;
typedef logos::class_hook_parser<iterator_type> class_hook_parser;
std::string const tweak_source_code = R"(
%hook SBLockScreenView
-(void)setCustomSlideToUnlockText:(id)arg1
{
arg1 = @"Changed the slider";
%orig(arg1);
}
%end
)";
using boost::spirit::ascii::space;
iterator_type iter = std::begin(tweak_source_code), end = std::end(tweak_source_code);
class_hook_parser g;
logos::class_hook emp;
bool r = phrase_parse(iter, end, g, space, emp);
if (r) {
std::cout << "Got: " << boost::fusion::as_vector(emp) << "n";
} else {
std::cout << "Something isn't workingn";
}
}
指纹
Got: (SBLockScreenView -(void)setCustomSlideToUnlockText:(id)arg1
arg1 = @"Changed the slider";
%orig(arg1);
)
相关文章:
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- C++A*算法并不总是在路径中具有目标节点
- 基于树莓pi的tensorflow lite量化ssd目标检测
- 为测试目标创建具有不同源文件夹的文件
- 不同语言中相同代码的不同行为
- 使用源向量作为目标
- 是否可以用C++/WinRT将windows 10.0.14393作为目标
- 为什么C++对链表中的下一个节点使用指针,而像 C# 或 Java 这样的语言只使用类 Node 的名称?
- r语言 - C++ 类型为"const std ::?
- 在 CMake 中为每个目标设置编译器/链接器标志
- '_HAS_CXX17'宏是否可用于自定义项目标头以启用C++17 语言集功能?
- CMake无法确定目标的链接器语言:fileloader
- CMake 错误:无法确定目标的链接语言
- 在Haxe中检测目标语言
- 提升精神解析目标C类语言
- 如何在SWIG包装C++代码中向目标语言(特别是Python)添加替代构造函数
- CMake CLion 问题 - 错误:无法确定目标"XYZ"的链接语言
- CMake错误:CMake无法确定目标myapp的链接器语言
- 目标 c - 如何在 c++ 语言 / getdate() 中定义表示时间值的值
- 具有两个目标和两种语言的生成文件