C ++ Boost qi рекурсивное построение правил
[Похоже, мои объяснения и ожидания не совсем ясны, поэтому я добавил точностьЯ хотел бы использовать эту функцию в конце поста
В настоящее время я работаю над грамматикой, используя повышение ци. У меня была конструкция цикла для правила, потому что мне нужно было построить его из элементов вектора. Я переписал его с простыми типами, и это выглядит так:
#include
// using boost 1.43.0
#include
#include
#include
namespace bqi = boost::spirit::qi;
typedef const char* Iterator;
// function that you can find [here][1]
template void test_phrase_parser(char const* input, P const& p, bool full_match = true);
int main()
{
// my working rule type:
bqi::rule myLoopBuiltRule;
std::vector v;
std::vector::const_iterator iv;
v.push_back("abc");
v.push_back("def");
v.push_back("ghi");
v.push_back("jkl");
myLoopBuiltRule = (! bqi::eps);
for(iv = v.begin() ; iv != v.end() ; iv++)
{
myLoopBuiltRule =
myLoopBuiltRule.copy() [ bqi::_val = bqi::_1 ]
| bqi::string(*iv) [ bqi::_val = bqi::_1 ]
;
}
debug(myLoopBuiltRule);
char s[] = " abc ";
test_phrase_parser(s, myLoopBuiltRule);
}
(ПохожеВот не хочет заменяться соответствующей гиперссылкой, поэтому вот адрес для поиска функции test_phrase_parser ():http://www.boost.org/doc/libs/1_43_0/libs/spirit/doc/html/spirit/qi/reference/basics.html)
Все было к лучшему в лучшем из всех миров ... пока мне не пришлось передать аргумент этому правилу. Вот новый тип правила:
// my not-anymore-working rule type:
bqi::rule myLoopBuiltRule;
INT * Тип только для целей, мой реальный указатель адресован гораздо более сложному классу ... но все же простой указатель.
Я сменилза' петля соответственно, т.е.
for(iv = v.begin() ; iv != v.end() ; iv++)
{
myLoopBuiltRule =
myLoopBuiltRule.copy()(bqi::_r1) [ bqi::_val = bqi::_1 ]
| bqi::string(*iv) [ bqi::_val = bqi::_1 ]
;
}
Мне пришлось добавить новое правило, потому что test_phrase_parser () не может угадать, какое значение нужно дать указателю int:
bqi::rule myInitialRule;
И измените все, что следует за циклом for:
myInitialRule = myLoopBuiltRule((int*)NULL);
debug(myLoopBuiltRule);
char s[] = " abc ";
test_phrase_parser(s, myInitialRule);
Потом все рухнуло
/home/sylvain.darras/software/repository/software/external/include/boost/boost_1_43_0/boost/spirit/home/qi/nonterminal/rule.hpp:199: error: no matching function for call to ‘assertion_failed(mpl_::failed************ (boost::spirit::qi::rule::operator=(const Expr&)
Тогда я сошел с ума и попробовал:
myLoopBuiltRule =
myLoopBuiltRule.copy(bqi::_r1) [ bqi::_val = bqi::_1 ]
| bqi::string(*iv) [ bqi::_val = bqi::_1 ]
->
error: no matching function for call to ‘boost::spirit::qi::rule::copy(const boost::phoenix::actor&)’
Тогда я разозлился и написал:
myLoopBuiltRule =
myLoopBuiltRule(bqi::_r1) [ bqi::_val = bqi::_1 ]
| bqi::string(*iv) [ bqi::_val = bqi::_1 ]
Который компилируется, поскольку он совершенно синтаксически корректен, но который великолепно переполняет стек, потому что он счастливо, красиво, рекурсивно вызывает себя к смерти ...
Затем я сошел с ума и набрал:
myLoopBuiltRule =
jf jhsgf jshdg fjsdgh fjsg jhsdg jhg sjfg jsgh df
Который, как вы, вероятно, ожидаете, не скомпилирован.
Вы представляете, что перед написанием вышеупомянутого романа я проверил в Интернете, но нене может найти ничего, что связано с copy () и передачей аргументов одновременно. Кто-нибудь уже сталкивался с этой проблемой? Я что-то пропустил?
Будьте уверены, что любая помощь будет по-настоящему оценена.
PS: Большое спасибо hkaiser, который, не зная об этом, ответил на многие мои проблемы boost :: qi через google (но этот).
Дальнейшая информация:
Цель моего парсера - читать файлы, написанные на заданном языке L. Цель моего поста - распространять мой "контекст» (то есть определения переменных и особенно постоянные значения, чтобы я мог вычислять выражения).
Количество типов переменных, с которыми я работаю, невелико, нобудет расти, поэтому я храню эти типы в классе контейнера. Я могу зациклить на этих управляемых типах.
Так что давайте'Рассмотрим псевдоалгоритм того, чего я хотел бы достичь:
LTypeList myTypes;
LTypeList::const_iterator iTypes;
bqi::rule myLoopBuiltRule;
myLoopBuiltRule = (! bqi::eps);
for(iTypes = myTypes.begin() ; iTypes != myTypes.end() ; iTypes++)
{
myLoopBuiltRule =
myLoopBuiltRule.copy()(bqi::_r1) [ bqi::_val = bqi::_1 ]
| iTypes->getRule()(bqi::_r1) [ bqi::_val = bqi::_1 ]
}
Это делается во время инициализации, а затем myLoopBuiltRule используется и повторно используется с другим LContext *, анализируя несколько типов. И поскольку некоторые типы L могут иметь границы, которые являются целочисленными выражениями, и что эти целочисленные выражения могут демонстрировать константы, я (думаю, что я) нуждаюсь в моем унаследованном атрибуте, чтобы использовать мой LContext и иметь возможность вычислять значение выражения.
Надеюсь яПрояснилось в моих намерениях.