gpt4 book ai didi

c++ - boost spirit 解析 objective-C 之类的语言

转载 作者:行者123 更新时间:2023-11-28 00:06:42 27 4
gpt4 key购买 nike

我正在尝试使用boost的 spirit 重新实现从iPhone越狱开发中解析perl脚本的logos。

输入的例子是:

%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_ - '}') >> '}';

注意事项:

  • 删除 skipper 允许您也删除 lexeme[] 指令。
  • 从“a-zA-Z”集中拒绝 - 是没有用的(它不在其中......)。
  • method_sig 现在包含所有空格(包括结尾的换行符)
  • 使用 BOOST_SPIRIT_DEBUG 深入了解为什么您的语法以神秘的方式运作

另请参阅:Boost spirit skipper issues

Live On Coliru

//#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 errored\n"
);

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 working\n";
}
}

打印

Got: (SBLockScreenView -(void)setCustomSlideToUnlockText:(id)arg1

arg1 = @"Changed the slider";
%orig(arg1);
)

关于c++ - boost spirit 解析 objective-C 之类的语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35303486/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com