促进精神规则-规则串联
boost spirit rule - rule concatenation
本文关键字:规则 更新时间:2023-10-16
我有一个字符串规则对的映射,我想以某种方式创建它们的"联合规则"(rule_tjoint_rule;)。如果我这样做:
joint_rule = convert_logformat["%h"] >> convert_logformat["%t"];
则具有parse_phrase的联合规则与字符串匹配
std::string entry = "127.0.0.1 [16/Aug/2012:01:50:02 +0000]";
但如果我以这种方式创建联合规则:
for (it = convert_logformat.begin(); it != convert_logformat.end(); it++)
{
joint_rule = joint_rule.copy() >> (*it).second.copy();
}
它与同一字符串不匹配。为什么?我怎样才能取得与后者类似的成就?
相关代码:
template <typename Iterator>
bool parse_logentry(Iterator first, Iterator last, std::vector<char>& ip, std::vector<char>& timestamp, std::vector<char>& req, unsigned int& status, unsigned int& transferred_bytes, std::vector<char>& referer, std::vector<char>& ua)
{
using boost::spirit::qi::char_;
using boost::spirit::qi::int_;
using boost::spirit::qi::uint_;
using boost::spirit::qi::phrase_parse;
using boost::spirit::ascii::space;
using boost::spirit::ascii::space_type;
using boost::phoenix::ref;
using boost::phoenix::push_back;
using boost::spirit::qi::_1;
using boost::spirit::qi::lexeme;
using boost::spirit::qi::rule;
typedef boost::spirit::qi::rule<Iterator, std::string(), space_type> rule_t;
rule_t ip_rule, timestamp_rule, user_rule, req_rule, ref_rule, ua_rule, bytes_rule, status_rule;
ip_rule %= lexeme[(+char_("0-9."))[ref(ip) = _1]];
timestamp_rule %= lexeme[('[' >> +(~char_(']')) >> ']')[ref(timestamp) = _1]];
user_rule %= lexeme[(+~char_(" "))];
req_rule %= lexeme[('"' >> +(~char_('"')) >> '"')[ref(req) = _1]];
ref_rule %= lexeme[('"' >> +(~char_('"')) >> '"')[ref(referer) = _1]];
ua_rule %= lexeme[('"' >> +(~char_('"')) >> '"')[ref(ua) = _1]];
bytes_rule %= uint_[ref(transferred_bytes) = _1];
status_rule %= uint_[ref(status) = _1];
std::map<std::string, rule_t> convert_logformat;
typename std::map<std::string, rule_t>::iterator it;
convert_logformat.insert(std::pair<std::string, rule_t>("%h", ip_rule));
convert_logformat.insert(std::pair<std::string, rule_t>("%t", timestamp_rule));
//convert_logformat.insert(std::pair<std::string, rule_t>("%r", req_rule));
//convert_logformat.insert(std::pair<std::string, rule_t>("%>s", status_rule));
//convert_logformat.insert(std::pair<std::string, rule_t>("%b", bytes_rule));
//convert_logformat.insert(std::pair<std::string, rule_t>("%u", user_rule));
//convert_logformat.insert(std::pair<std::string, rule_t>("%{User-agent}i", ua_rule));
//convert_logformat.insert(std::pair<std::string, rule_t>("%{Referer}i", ref_rule));
rule_t joint_rule;
//joint_rule = convert_logformat["%h"] >> convert_logformat["%t"];
for (it = convert_logformat.begin(); it != convert_logformat.end(); it++)
{
joint_rule = joint_rule.copy() >> (*it).second.copy();
std::cout << (*it).first << ": " << typeid((*it).second).name() << "n";
}
std::cout << "convert_logformath: " << typeid(convert_logformat["%h"]).name() << "n";
bool r = phrase_parse(first, last, joint_rule, space);
if (first != last)
return false;
return r;
}
Ahem。这真的很简单。您应该初始化您的变量:)
rule_t joint_rule; // what is it initialized to?
for (auto it = convert_logformat.begin(); it != convert_logformat.end(); it++)
{
joint_rule = joint_rule.copy() >> (*it).second.copy();
}
将第一行更改为
rule_t joint_rule = qi::eps;
它起作用:
sehe@mint12:/tmp$ ./test
127.0.0.1
16/Aug/2012:01:50:02 +0000
您的解析器缺少一些(好的)通用实践。请参阅下面的整理源代码(C++11)。
请注意,使用
map
来存储规则看起来很奇怪,因为映射迭代将按键排序,而不是按插入顺序。
在上实时查看代码http://liveworkspace.org/code/a7f2f94840d63fce43d8c3f56236330e
// #define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <typeinfo>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
template <typename Iterator>
struct Grammar : qi::grammar<Iterator, std::string(), qi::space_type>
{
Grammar() : Grammar::base_type(joint_rule)
{
using namespace qi;
ip_rule %= lexeme[ (+char_("0-9."))[phx::ref(ip) = _1] ];
timestamp_rule %= lexeme[ ('[' >> +(~char_(']')) >> ']')[phx::ref(timestamp) = _1] ];
user_rule %= lexeme[ (+~char_(" ")) ];
req_rule %= lexeme[ ('"' >> +(~char_('"')) >> '"')[phx::ref(req) = _1] ];
ref_rule %= lexeme[ ('"' >> +(~char_('"')) >> '"')[phx::ref(referer) = _1] ];
ua_rule %= lexeme[ ('"' >> +(~char_('"')) >> '"')[phx::ref(ua) = _1] ];
bytes_rule %= uint_[phx::ref(transferred_bytes) = _1 ];
status_rule %= uint_[phx::ref(status) = _1 ];
auto convert_logformat = std::map<std::string, rule_t> {
{ "%h" , ip_rule } ,
{ "%t" , timestamp_rule },
// { "%r" , req_rule } ,
// { "%>s" , status_rule } ,
// { "%b" , bytes_rule } ,
// { "%u" , user_rule } ,
// { "%{User-agent}i", ua_rule } ,
// { "%{Referer}i" , ref_rule }
};
joint_rule = eps;
for (auto const& p: convert_logformat)
{
joint_rule = joint_rule.copy() >> p.second.copy();
}
BOOST_SPIRIT_DEBUG_NODE(ip_rule);
BOOST_SPIRIT_DEBUG_NODE(timestamp_rule);
BOOST_SPIRIT_DEBUG_NODE(user_rule);
BOOST_SPIRIT_DEBUG_NODE(req_rule);
BOOST_SPIRIT_DEBUG_NODE(ref_rule);
BOOST_SPIRIT_DEBUG_NODE(ua_rule);
BOOST_SPIRIT_DEBUG_NODE(bytes_rule);
BOOST_SPIRIT_DEBUG_NODE(status_rule);
}
typedef qi::rule<Iterator, std::string(), qi::space_type> rule_t;
rule_t ip_rule, timestamp_rule, user_rule, req_rule, ref_rule, ua_rule, bytes_rule, status_rule;
rule_t joint_rule;
std::vector<char> ip;
std::vector<char> timestamp;
std::vector<char> req;
unsigned int status;
unsigned int transferred_bytes;
std::vector<char> referer;
std::vector<char> ua;
};
template <typename Iterator>
bool parse_logentry(Iterator first, Iterator last,
Grammar<Iterator>& parser)
{
bool r = phrase_parse(first, last, parser, qi::space);
return (r && (first == last));
}
int main(void)
{
std::string entry = "127.0.0.1 [16/Aug/2012:01:50:02 +0000]";
//std::string entry = "127.0.0.1 [16/Aug/2012:01:50:02 +0000] "GET /check.htm HTTP/1.1" 200 17 "-" "AgentName/0.1 libwww-perl/5.833"";
Grammar<std::string::iterator> parser;
if (parse_logentry(entry.begin(), entry.end(), parser))
{
for (auto i : parser.ip)
std::cout << i;
std::cout << "n";
for (auto ts: parser.timestamp)
std::cout << ts;
std::cout << "n";
}
else
{
std::cout << "not okn";
}
return 0;
}
请注意,除其他事项外,此设置允许您通过在开始时简单地定义BOOstrongPIRIT_DEBUG来启用语法调试。
相关文章:
- 此代码是否违反一个定义规则
- 生成文件不对文件使用隐式规则
- 变量可能尚未初始化[MIRA 2012规则9.1,强制性]
- 静态结构和一个定义规则
- 尽管遵循了规则,内存泄漏在哪里
- 这是关于成员访问规则的正确摘要吗
- uint_not_usable_without_attribute在业力规则中使用数字生成器时静态断言失败
- 增强精神解析器规则以检测语句中的特殊结尾
- 制作文件:没有规则来制定目标:如何设置正确的规则?
- 为什么此指针值不能转换为整数的规则是什么?
- 传递通用函数,用于梯形规则的数值积分
- C++内存模型中的确切规则阻止在获取操作之前重新排序
- 模板如何影响C++中隐式声明的规则?
- antlr 规则上下文是否可以独立于目标
- Bison/flex 在识别规则后等待输入
- 生成文件中隐式规则中的 -c 标志出错
- 单链接列表实现,规则为 3
- 指针算术规则中的"possibly-hypothetical"是什么意思?
- 假设声明中某些上下文中需要的名称查找规则是什么
- C++ 用于检查容器类中是否存在函数和隐式推导规则的概念