C ++ Boost qi construção de regra recursiva

[Parece que minhas explicações e expectativas não estão claras, então acrescentei precisão em como gostaria de usar o recurso no final do post]

Atualmente estou trabalhando em gramáticas usando o boost qi. Eu tive uma construção de loop para uma regra porque eu precisava construí-lo a partir dos elementos de um vetor. Eu reescrevi com tipos simples, e parece que:

#include <string>

// using boost 1.43.0
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_eps.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace bqi = boost::spirit::qi;

typedef const char* Iterator;

// function that you can find [here][1]
template<typename P> void test_phrase_parser(char const* input, P const& p, bool full_match = true);

int main()
{
    // my working rule type:
    bqi::rule<Iterator, std::string()> myLoopBuiltRule;
    std::vector<std::string> v;
    std::vector<std::string>::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);
}

(PareceAqui&nbsp;não quer ser substituído pelo hiperlink correspondente, então aqui está o endereço para encontrar a função test_phrase_parser ():http://www.boost.org/doc/libs/1_43_0/libs/spirit/doc/html/spirit/qi/reference/basics.html)

Tudo foi para o melhor no melhor de todos os mundos ... até que eu tive que passar um argumento para esta regra. Aqui está o novo tipo de regra:

    // my not-anymore-working rule type:
    bqi::rule<Iterator, std::string(int*)> myLoopBuiltRule;

O tipo 'int *' é apenas para propósito de propósito, meu ponteiro real está endereçando uma classe muito mais complexa ... mas ainda um mero ponteiro.

Eu mudei o meu 'for' loop de acordo, ou seja:

    for(iv = v.begin() ; iv != v.end() ; iv++)
    {
        myLoopBuiltRule =
                myLoopBuiltRule.copy()(bqi::_r1)    [ bqi::_val = bqi::_1 ]
                | bqi::string(*iv)      [ bqi::_val = bqi::_1 ]
                ;
    }

Eu tive que adicionar uma nova regra porque test_phrase_parser () não pode adivinhar qual valor deve ser dado ao ponteiro int:

bqi::rule<Iterator> myInitialRule;

E mude tudo o que seguiu o loop for:

myInitialRule = myLoopBuiltRule((int*)NULL);

debug(myLoopBuiltRule);

char s[] = "  abc ";

test_phrase_parser(s, myInitialRule);

Então tudo caiu:

/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<Iterator, T1, T2, T3, T4>::operator=(const Expr&)

Então eu fiquei louco e tentei:

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<const char*, std::string(int*), boost::fusion::unused_type, boost::fusion::unused_type, boost::fusion::unused_type>::copy(const boost::phoenix::actor<boost::spirit::attribute<1> >&)’

Então eu fiquei bravo e escrevi:

myLoopBuiltRule =
        myLoopBuiltRule(bqi::_r1)   [ bqi::_val = bqi::_1 ]
        | bqi::string(*iv)      [ bqi::_val = bqi::_1 ]

Que compila desde que é perfeitamente sintaticamente correto, mas que magnificamente transborda coz ele felizmente, bem, recursivamente, chama-se à morte ...

Então eu perdi a cabeça e digitei:

myLoopBuiltRule =
        jf jhsgf jshdg fjsdgh fjsg jhsdg jhg sjfg jsgh df

Que, como você provavelmente espera, não conseguiu compilar.

Você imagina que antes de escrever o romance acima, eu verifiquei na web, mas não descobri nada relacionado a copy () e argumento passando no mesmo tempo. Alguém já experimentou esse problema? Eu perdi alguma coisa?

Tenha certeza de que qualquer ajuda será realmente muito apreciada.

PS: Muito obrigado ao hkaiser que, sem saber, respondeu muito dos meus problemas de boost :: qi através do google (mas este aqui).

Outras informações:

O objetivo do meu analisador é ler arquivos escritos em uma determinada linguagem L. O objetivo do meu post é propagar o meu "contexto" (ou seja: definições de variáveis ​​e, especialmente, valores constantes, para que eu possa calcular expressões).

O número de tipos de variáveis ​​que eu manipulo é pequeno, mas é obrigado a crescer, então eu mantenho esses tipos em uma classe de contêiner. Eu posso fazer um loop nesses tipos gerenciados.

Então, vamos considerar um pseudo-algoritmo do que eu gostaria de obter:

LTypeList myTypes;
LTypeList::const_iterator iTypes;

bqi::rule<Iterator, LType(LContext*)> 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 ]
}

Isso é feito durante a inicialização e, em seguida, myLoopBuiltRule é usado e reutilizado com diferentes LContext *, analisando vários tipos. E já que alguns tipos L podem ter limites, que são expressões inteiras, e que essas expressões inteiras podem exibir constantes, eu (acho que preciso) do meu atributo herdado para levar meu LContext ao redor e ser capaz de calcular o valor da expressão.

Espero ter sido mais claro nas minhas intenções.