2016-04-21 17 views
9

libclang definisce solo 5 tipi di gettoni:libclang: come ottenere gettone semantica

  • CXToken_Punctuation
  • CXToken_Keyword
  • CXToken_Identifier
  • CXToken_Literal
  • CXToken_Comment

E 'possibile per avere informazioni più dettagliate su gettoni? Ad esempio, per il seguente codice sorgente:

struct Type; 
void foo(Type param); 

mi aspetterei l'uscita di essere come:

  • struct - parola chiave
  • Tipo - nome del tipo
  • ; - punteggiatura
  • vuoto - tipo/parola chiave
  • foo - nome della funzione
  • (- punteggiatura
  • Tipo - il tipo di parametro di funzione
  • param - funzione nome del parametro
  • ) - punteggiatura
  • ; - punteggiatura

Devo anche mappare tali entità in posizioni file.

risposta

7

In primo luogo, è probabilmente necessario un po 'di background su come funziona l'analisi. Un libro di testo sui compilatori sarebbe una risorsa utile. Innanzitutto, il file viene convertito in una serie di token; che ti dà identificatori, punteggiatura, ecc. Il codice che fa questo è chiamato un lexer. Quindi, il parser viene eseguito; questo converte un elenco di token in un AST (dichiarazioni strutturate/espressioni/ecc.).

clang tiene traccia delle varie parti di dichiarazioni ed espressioni, ma non nel modo in cui si sta descrivendo. Per una determinata dichiarazione di funzione, tiene traccia di cose come la posizione del nome della funzione e l'inizio della lista dei parametri, ma mantiene quelli in termini di posizioni nel file, non i token.

A CXToken è solo un token; non ci sono ulteriori informazioni semantiche associate oltre i cinque tipi che hai elencato. (È possibile ottenere il testo effettivo del token con clang_getTokenSpelling e la posizione con clang_getTokenExtent.) clang_annotateTokens fornisce CXCursor s, che consente di esaminare le dichiarazioni pertinenti.

Si noti che alcuni dettagli non sono esposti dall'API libclang; se hai bisogno di maggiori dettagli, potresti invece usare l'API C++ di clang.

+0

Alcuni link su dove basate le vostre osservazioni su come funziona Clang sarà molto utile (non sostenendo sei sbagliato, infatti ho visto la maggior parte di quello che dici mentre esploro libclang me stesso, semplicemente sottolineando come sarebbe educativo avere alcuni collegamenti per supportare le tue osservazioni) – Yannis

+0

So come funzionano i parser, ne ho implementato più di uno. Aggiungeremo più dettagli alla mia domanda più tardi Attualmente sto usando 'clang_annotateTokens' ma restituisce cursori con' CXCursorKind's inaspettati. – piotrekg2

+0

@ piotrekg2: se sai veramente come funzionano i parser, perché ti aspetti che il * token stream * abbia informazioni non-token come "nome funzione" e così via in esso? Si tratta di informazioni basate su parser, non basate su token. –

2

Stai cercando gli attributi del token spelling e location esposti da libclang. In C++ questi possono essere recuperati utilizzando le funzioni clang_getTokenLocation e clang_getTokenSpelling.Un minimo uso di queste funzioni (con i loro equivalenti pitone sarebbe:

s = ''' 
struct Type; 
void foo(Type param); 
''' 

idx = clang.cindex.Index.create() 
tu = idx.parse('tmp.cpp', args=['-std=c++11'], unsaved_files=[('tmp.cpp', s)], options=0) 
for t in tu.get_tokens(extent=tu.cursor.extent): 
    print t.kind, t.spelling, t.location 

Dà:

TokenKind.KEYWORD struct <SourceLocation file 'tmp.cpp', line 2, column 1> 
TokenKind.IDENTIFIER Type <SourceLocation file 'tmp.cpp', line 2, column 8> 
TokenKind.PUNCTUATION ; <SourceLocation file 'tmp.cpp', line 2, column 12> 
TokenKind.KEYWORD void <SourceLocation file 'tmp.cpp', line 3, column 1> 
TokenKind.IDENTIFIER foo <SourceLocation file 'tmp.cpp', line 3, column 6> 
TokenKind.PUNCTUATION (<SourceLocation file 'tmp.cpp', line 3, column 9> 
TokenKind.IDENTIFIER Type <SourceLocation file 'tmp.cpp', line 3, column 10> 
TokenKind.IDENTIFIER param <SourceLocation file 'tmp.cpp', line 3, column 15> 
TokenKind.PUNCTUATION) <SourceLocation file 'tmp.cpp', line 3, column 20> 
TokenKind.PUNCTUATION ; <SourceLocation file 'tmp.cpp', line 3, column 21>