Domanda

La mia situazione: sono nuovo in Spirit, devo usare VC6 e sto usando Spirit 1.6.4.

Ho una linea che assomiglia a questa:

//The Description;DESCRIPTION;;

Voglio mettere il testo DESCRIPTION in una stringa se la riga inizia con // The Description; .

Ho qualcosa che funziona ma non mi sembra così elegante:

vector<char> vDescription; // std::string doesn't work due to missing ::clear() in VC6's STL implementation
if(parse(chars,
    // Begin grammar
    (
       as_lower_d["//the description;"]
    >> (+~ch_p(';'))[assign(vDescription)]
    ),
    // End grammar
    space_p).hit)
{
    const string desc(vDescription.begin(), vDescription.end());
}

Mi piacerebbe molto di più assegnare tutti i caratteri stampabili al ';' successivo ma quanto segue non funzionerà perché parse (...). hit == false

parse(chars,
        // Begin grammar
        (
           as_lower_d["//the description;"]
        >> (+print_p)[assign(vDescription)]
        >> ';'
        ),
        // End grammar
        space_p).hit)

Come faccio a farlo colpire?

È stato utile?

Soluzione

Potresti provare a utilizzare confix_p :

confix_p(as_lower_d["//the description;"],
         (+print_p)[assign(vDescription)],
         ch_p(';')
        )

Dovrebbe essere equivalente a La risposta di Fred .

Il motivo per cui il tuo codice fallisce è perché print_p è avido . Il parser + print_p consumerà caratteri fino a quando non incontra la fine dell'input o un carattere non stampabile. Il punto e virgola è stampabile, quindi print_p lo rivendica. Il tuo input si esaurisce, la variabile viene assegnata e la corrispondenza non riesce & # 8212; non è rimasto nulla che corrisponda all'ultimo punto e virgola del tuo parser.

La risposta di Fred costruisce un nuovo parser, (print_p - ';') , che corrisponde a tutto ciò che print_p , tranne i punti e virgola. " Abbina tutto tranne X , quindi abbina X " è un modello comune, quindi confix_p viene fornito come scorciatoia per costruire quel tipo di parser. La documentazione suggerisce di usarlo per analizzare i commenti in stile C o Pascal, ma non è necessario.

Affinché il tuo codice funzioni, Spirit dovrebbe riconoscere che l'avido print_p corrispondeva troppo e quindi backtrack per consentire una corrispondenza inferiore. Ma anche se lo Spirito tornerà indietro, non tornerà indietro al "mezzo" di ciò che un sub-parser corrisponderebbe altrimenti avidamente. Tornerà indietro al prossimo "punto di scelta", " ma la tua grammatica non ne ha. Vedi Backtracking esaustivo e goloso RD nella documentazione di Spirit.

Altri suggerimenti

Non hai successo perché ';' è abbinato a print_p. Prova questo:

parse(chars,
    // Begin grammar
    (
       as_lower_d["//the description;"]
    >> (+(print_p-';'))[assign(vDescription)]
    >> ';'
    ),
    // End grammar
    space_p).hit)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top