私はhttpパーサーに取り組んでいます。代替演算子を使用して解析しようとすると、問題が見つかりました。hold[]を使用して修正できるのは、属性の値に関するものではありません。この問題は、ルールの先頭が似ている 2 つのルールがある場合に発生します。私の問題を示すためのいくつかの簡単なルールを次に示します。
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"
ただし、最初のルールの前に2番目のルールを切り替えると。パーサーは true を返します。問題は、パーサーが最初のルールで入力を消費し、最初のルールが Fail であることが判明したためだと思います。最初のルールの代替である 2 番目のルールには戻りません。
最初のルールを適用しようとしまし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_wo_question」の前に「rule_w_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") に進むことができません。最後に、プログラムは「[不正]」を返します
2 番目のバージョンでは、「rule_wo_question」の前に「rule_w_question」を切り替えます。これが、パーサーが結果として "[correct]" を返す理由です。
================================================== ============ pthread と boost_filesystem にリンクされたブースト 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