C ++ Boost qi construcción de la regla recursiva

[Parece que mis explicaciones y expectativas no son claras en absoluto, así que agregué precisión en cómo me gustaría usar la función al final del post]

Actualmente estoy trabajando en gramáticas usando boost qi. Tenía una construcción de bucle para una regla porque necesitaba construirla a partir de los elementos de un vector. Lo he reescrito con tipos simples, y 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);
}

(Pareceaquí no desea ser reemplazado por el hipervínculo correspondiente, por lo que aquí está la dirección para buscar la función test_phrase_parser ():http://www.boost.org/doc/libs/1_43_0/libs/spirit/doc/html/spirit/qi/reference/basics.html)

Todo fue por lo mejor en el mejor de los mundos ... hasta que tuve que pasar un argumento a esta regla. Aquí está el nuevo tipo de regla:

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

El tipo 'int *' es solo para fines de ejemplo, mi puntero real está dirigiéndose a una clase mucho más compleja ... pero aún así es un mero puntero.

Cambié mi bucle 'for' en consecuencia, es decir:

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

Tuve que agregar una nueva regla porque test_phrase_parser () no puede adivinar qué valor se le dará al puntero int:

bqi::rule<Iterator> myInitialRule;

Y cambia todo lo que siguió al bucle for:

myInitialRule = myLoopBuiltRule((int*)NULL);

debug(myLoopBuiltRule);

char s[] = "  abc ";

test_phrase_parser(s, myInitialRule);

Entonces todo se estrelló:

/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&)

Entonces me volví loco y lo intenté:

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> >&)’

Entonces me enojé y escribí:

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

El que compila, ya que es perfectamente correcto sintácticamente, pero que apila magníficamente los desbordamientos, lo hace feliz, amable y recursivamente, se mata a sí mismo ...

Entonces perdí mi mente y tecleé:

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

Que, como es de esperar, no se ha podido compilar.

Te imaginas que antes de escribir la novela anterior, consulté en la web, pero no encontré nada relacionado con copy () y el argumento que pasaba al mismo tiempo. ¿Alguien ya ha experimentado este problema? ¿Me he perdido algo?

Tenga la seguridad de que cualquier ayuda será realmente apreciada.

PD: Muchas gracias a hkaiser que, sin saberlo, respondió muchos de mis problemas de impulso :: qi a través de google (pero este).

Más información:

El propósito de mi analizador es leer los archivos escritos en un idioma L. determinado. El propósito de mi publicación es propagar mi "contexto" (es decir, las definiciones de variables y especialmente los valores constantes, por lo que puedo calcular expresiones).

El número de tipos de variables que manejo es pequeño, pero está obligado a crecer, por lo que mantengo estos tipos en una clase contenedora. Puedo hacer un bucle en estos tipos gestionados.

Entonces, consideremos un pseudo-algoritmo de lo que me gustaría lograr:

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 ]
}

Esto se hace durante la inicialización y luego myLoopBuiltRule se usa y se reutiliza con diferentes LContext *, analizando múltiples tipos. Y dado que algunos tipos L pueden tener límites, que son expresiones enteras, y que estas expresiones enteras pueden exhibir constantes, yo (creo que yo) necesito mi atributo heredado para llevar mi LContext alrededor y poder calcular el valor de la expresión.

Espero haber sido más clara en mis intenciones.

Respuestas a la pregunta(1)

Su respuesta a la pregunta