Il modulo parser fornisce un'interfaccia al parser interno ed al compilatore bytecode di Python. Lo scopo primario di questa interfaccia è quello di permettere al codice Python di modificare l'albero di analisi di una espressione Python e di creare da essa del codice eseguibile. Tutto ciò è meglio che provare ad analizzare e modificare un frammento arbitrario di codice di Python come se fosse una stringa, perché l'analisi viene svolta nella medesima maniera di quella del codice che forma l'applicazione. È anche più veloce.
Ci sono poche cose nuove da notare su questo modulo importanti al fine di utilizzare al meglio le strutture dati create. Pur non essendo un tutorial sulla modifica degli alberi di analisi del codice Python vengono comunque presentati alcuni esempi d'uso del modulo parser.
Molto importante, viene richiesta una buona comprensione della grammatica di Python elaborata dal parser interno. Per delle informazioni complete sulla sintassi del linguaggio, fate riferimento al Manuale di riferimento di Python. Il parser stesso viene creato da una specifica grammaticale definita nella distribuzione standard Python nel file Grammar/Grammar. Quando vengono creati dalle funzioni expr() o suite() descritte sotto, gli alberi di analisi conservati negli oggetti AST creati da questo modulo rappresentano l'output reale del parser interno. Gli oggetti AST creati da sequence2ast() simulano fedelmente queste strutture. Fate attenzione che i valori delle sequenze che vengono considerate ``corrette'' varieranno da una versione all'altra di Python, come anche la grammatica formale del linguaggio. In ogni caso, trasporre codice da una versione di Python ad un'altra come testo sorgente permetterà sempre la creazione di alberi di analisi corretti nella versione di destinazione, con la sola restrizione che migrando verso una versione più vecchia non verranno supportati molti dei costrutti linguistici più recenti. Gli alberi di analisi non sono in genere compatibili da una versione all'altra, mentre il codice sorgente è stato sempre compatibile con le versione successive.
Ogni elemento delle sequenze restituite da ast2list() o
ast2tuple() ha una forma semplice. Le sequenze che
rappresentano elementi non terminali nella grammatica hanno sempre
lunghezza più grande di uno. Il primo elemento è un intero che
identifica una produzione nella grammatica. Questi interi prendono
nomi simbolici nel file header C Include/graminit.h e
nel modulo Python symbol. Ogni elemento
aggiuntivo della sequenza rappresenta un componente della produzione
come riscontrato nella stringa di input: ci sono sempre sequenze che
hanno la stessa forma dei genitori. Un aspetto importante di questa
struttura che dovrebbe essere notato è che le parole chiave usate per
identificare il tipo del nodo genitore, come la parola chiave
if in un if_stmt, vengono incluse nell'albero dei
nodi senza uno speciale trattamento. Per esempio, la parola chiave
if viene rappresentata dalla tupla (1, 'if')
, dove
1
è il valore numerico associato con tutti i token
NAME, inclusi i nomi delle variabili e delle funzioni
definite dall'utente. In una forma alternativa restituita quando
viene richiesta l'informazione su di un numero di riga, lo stesso
simbolo può venire rappresentato come (1, 'if', 12)
, dove il
12
rappresenta il numero di riga in cui è stato trovato il
simbolo terminale.
Gli elementi terminali vengono rappresentati nello stesso modo, ma senza nessun elemento figlio e l'aggiunta del testo sorgente con il quale era stato identificato. L'esempio della parola chiave if lo descrive. I vari tipi di simboli terminali vengono definiti nel file header C Include/token.h ed nel modulo Python token.
Non vengono richiesti gli oggetti AST per supportare le funzionalità di questo modulo, ma vengono forniti per tre scopi: permettere ad un'applicazione di ammortizzare il costo dell'elaborazione di alberi di analisi complessi, fornire una rappresentazione dell'albero di analisi che conservi spazio in memoria quando viene confrontato con la rappresentazione di liste o tuple Python, e semplificare la creazione di moduli aggiuntivi in C che manipolano gli alberi di analisi. Si può creare una semplice classe ``wrapper'' in Python per nascondere l'uso di oggetti AST.
Il modulo parser definisce funzioni per pochi scopi distinti. Gli scopi più importanti sono la creazione di oggetti AST e la conversione di oggetti AST in altre rappresentazioni, come alberi di analisi ed oggetti di codice compilato, ma ci sono anche funzioni che servono ad interrogare il tipo di albero di analisi rappresentato da un oggetto AST.
Vedete anche: