【发布时间】:2011-09-18 03:35:20
【问题描述】:
我正在开发一个 http 解析器。当我尝试使用替代运算符进行解析时,它发现了一个问题。我可以使用hold []修复它们与属性中的值无关。当开头有两条相似的规则时,就会出现问题 规则。这里有一些简单的规则来证明我的问题;
qi::rule<string_iterator> some_rule(
(char_('/') >> *char_("0-9")) /*first rule accept /123..*/
| (char_('/') >> *char_("a-z")) /*second rule accept /abc..*/
);
然后我使用qi::parse 解析这条规则,如果输入字符串喜欢,它将失败;
"/abcd"
但是,当我在第一条规则之前切换第二条规则时。解析器将返回 true 我认为问题是因为当解析器使用第一条规则使用输入时 然后它发现第一个规则是失败。它不会回到第二条规则,即 第一条规则的替代方案。
我尝试将hold[] 放在第一条规则中,但这仅有助于生成属性。它
不能解决这个问题。我不知道如何解决这个问题,因为 HTTP 有很多
规则开头的规则与其他规则相同。
===========关于我的代码的更多信息=============================
这是我解析字符串的函数
typedef std::string::const_iterator string_iterator;
typedef qi::rule<string_iterator, std::string()> rules_t;
void parse_to_string(const std::string& s, rules_t& r, std::string& result)
{
using namespace rule;
using qi::parse;
std::string::const_iterator iter = s.begin();
std::string::const_iterator end = s.end();
bool err = parse(iter, end, r, result);
if ( err && (iter==end) )
{
std::cout << "[correct]" << result << std::endl;
}
else
{
std::cout << "[incorrect]" << s << std::endl;
std::cout << "[dead with]" << result << std::endl;
}
}
我主要有这段代码;
std::string result;
result = "";
str = "/htmlquery?";
qi::rule<string_iterator, std::string()> rule_wo_question( char_('/') >> *char_("a-z"));
qi::rule<string_iterator, std::string()> rule_w_question( char_('/') >> *char_("a-z") >> char_('?'));
qi::rule<string_iterator, std::string()> whatever_rule( rule_wo_question
| rule_w_question
);
parse_to_string(str, whatever_rule, result);
我得到了这个结果;
[不正确]/htmlquery? [dead with]/htmlquery
但是当我像这样切换规则时; (我把“rule_w_question”放在“rule_wo_question”之前)
std::string result;
result = "";
str = "/htmlquery?";
qi::rule<string_iterator, std::string()> rule_wo_question( char_('/') >> *char_("a-z"));
qi::rule<string_iterator, std::string()> rule_w_question( char_('/') >> *char_("a-z") >> char_('?'));
qi::rule<string_iterator, std::string()> whatever_rule( rule_w_question
| rule_wo_question
);
parse_to_string(str, whatever_rule, result);
输出将是; [正确]/htmlquery?
第一个版本(错误的)似乎解析消耗'/htmlquery'(“rule_wo_question”),然后它发现它不能消耗'?这使这条规则失效。 那么这个规则就不能转到替代规则 ("rule_w_question") 。最后程序返回“[不正确]”
第二个版本我在“rule_wo_question”之前切换了“rule_w_question”。这就是解析器返回“[正确]”的原因。
================================================ ================ 我与 pthread 和 boost_filesystem 链接的 boost 1.47 的整个代码 这是我的主要.c
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/network/protocol.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/bind.hpp>
#include <boost/spirit/include/qi_uint.hpp>
using namespace boost::spirit::qi;
namespace qi = boost::spirit::qi;
typedef std::string::const_iterator string_iterator;
typedef qi::rule<string_iterator, std::string()> rules_t;
void parse_to_string(const std::string& s, rules_t& r, std::string& result)
{
using qi::parse;
std::string::const_iterator iter = s.begin();
std::string::const_iterator end = s.end();
bool err = parse(iter, end, r, result);
if ( err && (iter==end) )
{
std::cout << "[correct]" << result << std::endl;
}
else
{
std::cout << "[incorrect]" << s << std::endl;
std::cout << "[dead with]" << result << std::endl;
}
}
int main()
{
std::string str, result;
result = "";
str = "/htmlquery?";
qi::rule<string_iterator, std::string()> rule_wo_question( char_('/') >> *char_("a-z"));
qi::rule<string_iterator, std::string()> rule_w_question( char_('/') >> *char_("a-z") >> char_('?'));
qi::rule<string_iterator, std::string()> whatever_rule( rule_wo_question
| rule_w_question
);
parse_to_string(str, whatever_rule, result);
return 0;
}
结果是
[incorrect]/htmlquery?
[dead with]/htmlquery
【问题讨论】:
-
你能把你的语法贴成EBNF格式吗?它有助于发现任何错误以及确定您提出的语法是否得到 Spirit 的支持(即 LL(0))。
-
您上面的代码 sn-p 看起来没问题,因此还有其他问题。请发布一个最小的独立代码示例来暴露您的问题。
-
谁能帮助我。我发布了我的代码的完整版本。我真的需要帮助!非常感谢
标签: c++ boost boost-spirit-qi