以下程序是一個人爲示例(從我工作的較大語法中減少)顯示出奇怪的行爲。提升精神,從語義動作返回的值干擾規則屬性
程序運行的輸出是「hello」,不正確。
如果我從quoted_string
規則中刪除(在此示例中無用)語義操作,則輸出爲預期的「foo = hello」。
#define BOOST_RESULT_OF_USE_DECLTYPE
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <vector>
#include <string>
#include <iostream>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include "utils.hpp"
namespace t {
using std::vector;
using std::string;
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
template <typename Iterator, typename Skipper=qi::space_type>
struct G1 : qi::grammar<Iterator, string(), Skipper> {
template <typename T>
using rule = qi::rule<Iterator, T, Skipper>;
qi::rule<Iterator, string(), qi::locals<char>> quoted_string;
rule<string()> start;
G1() : G1::base_type(start, "G1") {
{
using qi::_1;
using qi::_a;
using attr_signature = vector<char>;
auto handler = [](attr_signature const& elements) -> string {
string output;
for(auto& e : elements) {
output += e;
}
return output;
};
quoted_string = (qi::omit[qi::char_("'\"")[_a = _1]]
>> +(qi::char_ - qi::char_(_a))
>> qi::lit(_a))[qi::_val = phx::bind(handler, _1)];
}
start = qi::string("foo") >> -(qi::string("=") >> quoted_string);
}
};
string parse(string const input) {
G1<string::const_iterator> g;
string result;
phrase_parse(begin(input), end(input), g, qi::standard::space, result);
return result;
}
};
int main() {
using namespace std;
auto r = t::parse("foo='hello'");
cout << r << endl;
}
我一定能找到一個解決辦法,但我會找出我錯過
我對不起,我不能提供比解決方法更好的東西,但如果它有幫助,將語義操作更改爲'qi :: _ val + = phx:bind(handler,_1)'使其正常工作。看起來''quoted_string'屬性的字符串是對'start'屬性相同的字符串的引用。如果沒有語義動作,'+(qi :: char_ - qi :: char _(_ a))'只是將一系列字符推回到字符串中,並且您得到正確的值。用你原來的語義動作,'start'字符串被'hello'覆蓋。 – llonesmiz