2012-05-09 17 views
6

Ho un semplice parser di file di configurazione creato da spirit :: lex e spirit :: qi. Quando il lexer raggiunge il modello include "path", voglio che il testo del file sia incluso. Come forse sapete, lo spirito :: :: lexer begin() avvia il processo di scansione:Come implementare le direttive include usando boost :: spirit :: lex?

// Read file contents into a std::string 
... 

// _first and _last are const char* 
_first = _contents.c_str(); 
_last = &_first[_input.size()]; 

// _token is a lexer::iterator_type for the current token 
_token = _lexer.begin(_first, _last); 

La mia idea è quella di avere uno stack che memorizza lo stato lexer rappresentato come una struct:

struct LexerState 
{ 
    const char* first; 
    const char* last; 
    std::string contents; 
}; 

Il il lexer dovrebbe riconoscere il modello per include "path" e in un'azione semantica estrarre il percorso del file di inclusione. Quindi, lo stato del lexer corrente viene inserito nello stack, il contenuto del file viene caricato in una stringa e il nuovo stato viene inizializzato come sopra usando lexer :: begin().

Quando il lexer trova il carattere EOF, lo stack viene fatto scoppiare e lexer :: begin() viene chiamato utilizzando le precedenti variabili di stato del lexer.

È corretto chiamare ripetutamente lexer :: begin() in questo modo? Come posso ottenere che lex :: lexer riconosca lo schema include "path" e il carattere EOF senza restituire un token al parser qi?

Infine, ci sono modi alternativi o migliori per realizzare questo?

risposta

3

Avere uno sguardo a come Boost Wave fa cose:

La biblioteca preprocessore Wave C++ utilizza la libreria di costruzione Spirit parser per implementare un lexer C++ con ISO/ANSI Standard funzionalità di pre-elaborazione conformi. Espone un'interfaccia iteratore, che restituisce il token preelaborato corrente dal flusso di input. Questo token preelaborato viene generato al volo mentre itera su una sequenza di iteratori del preprocessore (nella terminologia della STL questi iteratori sono iteratori in avanti).

E caratteristiche riguardanti:

Il C++ preprocessore fornisce quattro strutture separate che è possibile utilizzare come meglio credi:

  • L'inclusione di file di intestazione
  • Macro di espansione
  • Compilazione condizionale
  • Controllo di linea

loro Quick Start Sample mostra come usereste Boost interfaccia lexer di Wave.

Problemi correlati