2012-04-24 11 views
5

Ho un file C-Header che definisce un paio di stucchi, contenenti più array di caratteri.Analisi/lettura di file C-Header utilizzando Java

Mi piacerebbe analizzare questi file utilizzando Java. Esiste una libreria per leggere i file C-Header in una struttura o c'è un parser di flusso che capisce i file C-Header?

Solo per più background (sto solo cercando un parser C-Header, non una soluzione per questo particolare problema): Ho un file di testo contenente dati e un file C-Header che spiega la struttura. Entrambi sono un po 'dinamici, quindi non voglio generare file di classe Java.

esempio:

#define TYPE1 
typedef struct type1 
{ 
char name1[10]; 
char name2[5]; 
} 
#endif 

Tipo2, Tipo3 ecc sono simili.

Struttura dei dati:

type1ffffffffffaaaaa 
+0

le pagine man di lex e yacc (flex e bisonte) possono aiutare –

+0

Oh, buon punto, ho dimenticato di yacc. Speravo che ci sarebbe già una soluzione esistente per questo. Ma credo di poter creare il mio parser di streaming usando yacc. – PhilW

+0

@PhilW, hai creato il parser? Ho bisogno di analizzare C Header contenente le definizioni del preprocessore (solo costanti intere). Ho bisogno di ottenere queste costanti dall'applicazione C Header a Java. Certo che sto cercando una soluzione pronta per l'uso prima di implementare la mia =) –

risposta

12

È possibile utilizzare un parser C esistente per Java. Fa molto più dell'analisi dei file di intestazione, ovviamente, ma non dovrebbe farti male.

Utilizziamo il parser dal progetto Eclipse CDT. Questo è un plugin Eclipse, ma lo usiamo con successo al di fuori di Eclipse, dobbiamo solo raggruppare 3 file JAR di Eclipse con il parser JAR.

Per utilizzare il parser CDT, iniziare con un'implementazione di org.eclipse.cdt.core.model.ILanguage, ad esempio org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage. Puoi chiamare getTranslationUnit su di esso, passare il codice e alcune cose di supporto. Un file di codice è rappresentato da un'istanza org.eclipse.cdt.core.parser.FileContent (almeno in CDT7, questo sembra cambiare molto). Il modo più semplice per creare tale oggetto è FileContent.createForExternalFileLocation(filename) o FileContent.create(filename, content). In questo modo non devi preoccuparti delle cose di Eclipse IFile, che sembrano funzionare solo all'interno di progetti e spazi di lavoro.

Il IASTTranslationUnit che si ottiene rappresenta l'intero AST del file. Tutti i nodi in questo caso sono istanze di tipi IASTSomething, ad esempio IASTDeclaration ecc. È possibile implementare la propria sottoclasse di org.eclipse.cdt.core.dom.ast.ASTVisitor per scorrere l'AST utilizzando il modello di visitatore. Se hai bisogno di ulteriore aiuto, basta chiedere.

I file JAR che utilizziamo sono org.eclipse.cdt.core.jar, org.eclipse.core.resources.jar, org.eclipse.equinox.common.jar e org.eclipse.osgi.jar.

Edit: avevo trovato un documento che contiene frammenti di codice sorgente per questo: "Utilizzo del Tooling Eclipse C/C++ per lo sviluppo come un robusto, perfettamente funzionante, mantenuto attivamente, Open Source C++ Parser", ma è non più disponibile online (solo come versione abbreviata).

+0

Suona come una buona misura! Ti dispiacerebbe introdurre alcune parole chiave o indicazioni su come farlo? (quali sono le classi principali in questo scenario?) – PhilW

+0

In realtà ho una domanda: nel mio esempio sopra, ho una macro "#define type1" - come faccio a far visitare il mio ASTVisitor? – PhilW

+0

Non sono sicuro di come supporti le istruzioni del pre-processore, in quanto il nostro codice non ne ha. Ma ci sono alcuni metodi in 'IASTTranslationUnit' che sembrano darti accesso a istruzioni pre-processore come' # define'. –

4

Esempio con Eclipse CDT con solo 2 barattoli.
Nell'esempio ha una classe che visualizza la struttura del file di origine come un albero e un altro esempio che crea interazioni sull'ap ...

Un dettaglio è che con questa api (parser CDT Eclipse) è possibile eseguire l'analisi da una stringa in memoria.

Un altro esempio di utilizzo è:
https://github.com/ricardojlrufino/cplus-libparser
Library per estrazione metadati (informazioni su classi, metodi variabili) del codice sorgente in C/C++.

Visualizza file: https://github.com/ricardojlrufino/cplus-libparser/blob/master/src/main/java/br/com/criativasoft/cpluslibparser/SourceParser.java

3

Come già accennato, CDT è perfetto per questo compito. Ma a differenza di quanto descritto sopra l'ho usato da un plugin ed è stato in grado di usare IFiles. Quindi tutto è molto più semplice. Per ottenere il "ITranslationUnit" basta fare:

ITranslationUnit tu = (ITranslationUnit) CoreModel.getDefault().create(myIFile); 
IASTTranslationUnit ias = tu.getAST(); 

stavo cioè alla ricerca di un #define speciale, quindi ho potuto solo:

ppc = ias.getAllPreprocessorStatements(); 

per ottenere tutte le istruzioni di codice preelaborate, ogni dichiarazione in ordine -elemento. Perfettamente facile.

Problemi correlati