런타임시 임의의 수의 규칙을 동적으로 결합하는 Boost.Spirit.Qi 방법이 있는지 궁금합니다. Boost.Spirit의 내부 동작은 여전히 나에게 약간의 수수께끼이지만, 규칙이 객체로 구현 되었기 때문에 실현 가능성이 있습니다. 내 동기는 내 문법의 특정 부분을 쉽게 확장 가능하게 만드는 것입니다.런타임시 Boost.Spirit.Qi 규칙을 동적으로 결합하십시오 (임의의 대체 번호)
error C2440: 'initializing' : cannot convert from 'boost::fusion::void_' to 'int &'
내 의심이 grammar.copy()
에 상속 된 속성을 전달하지 않음으로써 발생한다는 것입니다 : 비주얼 스튜디오 2010에 의해 주어진
namespace qi = boost::spirit::qi;
namespace px = boost::phoenix;
typedef std::string::const_iterator iterator_t;
template<typename Expr>
inline bool parse_full(const std::string& input, const Expr& expr)
{
iterator_t first(input.begin()), last(input.end());
bool result = qi::phrase_parse(first, last, expr, boost::spirit::ascii::space);
return first == input.end() && result;
}
void no_op() {}
int main(int argc, char *argv[])
{
int attr = -1;
// "Static" version - Works fine!
/*
qi::rule<iterator_t, void(int&)> grammar;
qi::rule<iterator_t, void(int&)> ruleA = qi::char_('a')[qi::_r1 = px::val(0)];
qi::rule<iterator_t, void(int&)> ruleB = qi::char_('b')[qi::_r1 = px::val(1)];
qi::rule<iterator_t, void(int&)> ruleC = qi::char_('c')[qi::_r1 = px::val(2)];
grammar =
ruleA(qi::_r1) | //[no_op]
ruleB(qi::_r1) | //[no_op]
ruleC(qi::_r1); //[no_op]
*/
// "Dynamic" version - Does not compile! :(
std::vector<qi::rule<iterator_t, void(int&)>> rules;
rules.push_back(qi::char_('a')[qi::_r1 = px::val(0)]);
rules.push_back(qi::char_('b')[qi::_r1 = px::val(1)]);
rules.push_back(qi::char_('c')[qi::_r1 = px::val(2)]);
std::vector<qi::rule<iterator_t, void(int&)>>::iterator i(rules.begin()), last(rules.end());
qi::rule<iterator_t, void(int&)> grammar;
grammar = (*i)(qi::_r1);
for(++i; i!=last; ++i)
{
grammar = grammar.copy() | (*i)(qi::_r1);
}
// Tests
if(parse_full("a", grammar(px::ref(attr)))) std::cout << attr << std::endl;
if(parse_full("b", grammar(px::ref(attr)))) std::cout << attr << std::endl;
if(parse_full("c", grammar(px::ref(attr)))) std::cout << attr << std::endl;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
return 0;
}
오류는 다음과 같습니다
는 다음과 같은 인위적인 예를 생각해 보자. 불행히도이 작업을 수행하는 쉬운 방법을 찾을 수 없었으므로 해결 방법을 선택했습니다. 결과적으로, 나는 하나의 마지막 버전을 가지고있다. (그리고 나는 지금까지 주위에 고집 한 누구에게나 감사하고 싶다.). 행동이 정말 이상한되고,
// "Dynamic" version - Kind of works! :-/
std::vector<qi::rule<iterator_t, void(int&)>> rules;
rules.push_back(qi::char_('a')[qi::_r1 = px::val(0)]);
rules.push_back(qi::char_('b')[qi::_r1 = px::val(1)]);
rules.push_back(qi::char_('c')[qi::_r1 = px::val(2)]);
std::vector<qi::rule<iterator_t, void(int&)>>::iterator i(rules.begin()), last(rules.end());
qi::rule<iterator_t, int()> temp;
temp = (*i)(qi::_val); //[no_op]
for(++i; i!=last; ++i)
{
temp = temp.copy() | (*i)(qi::_val); //[no_op]
}
qi::rule<iterator_t, void(int&)> grammar;
grammar = temp[qi::_r1 = qi::_1];
그러나, 한 번 I (예 : "[no_op]"와 같은) 간단한 의미 조치를 첨부 : 이것은 실제로 작동하는 것 같다. 이전과 같이 0,1,2를 인쇄하는 대신 0,0,2를 인쇄합니다. 그래서 궁금 하군요, 내가 정의되지 않은 동작의 결과를 달성하기 위해 노력하고있어 무엇입니까? 이거 버그 야? 또는 아마도 내가 뭔가를 사용하고 있습니까 (예 : 의미 론적 액션)? 잘못된 방법일까요?
감사합니다! 당신의 대답은 매우 유망 해 보입니다. 불행히도 지금 당장 테스트 할 방법이 없습니다. 나는 그것을 시험해 볼 기회를 얻 자마자 그것을 받아 들일 것이다! – kloffy
이 수정 된 효과가 있습니까? –
거의 2 년 늦게 진심으로 사과드립니다. 나는이 솔루션을 테스트하기 위해 돌아왔다. – kloffy