PyParsing

, par MiKaël Navarro

Exemples d’utilisation des modules pyparsing et ordereddict pour le parsing d’un fichier en Python < 2.5

Flatten GDB dump

L’idée est ici d’analyser le dump GDB d’une structure de donnée afin de la représenter sous la forme clef (= nom du champ) / valeur.

La procédure est :

 Exécuter un script GDB afin de générer un dump de la structure à analyser :

spy.gdb
$ spy.gdb --batch --command=spy.gdb --args sample.exe > sample.log

 La sortie est ensuite nettoyé du superflu :

$ sed -n "/\$1 = {/,/^}/p" sample.log | sed -e "s/\$1 = {/{/" > sample.dump
$ cat sample.dump
{
 a = 1,
 b = 2,
 c = 3,
 tab = { 0, 1, 2, 3 },
 tab2 = { { 1, 2 }, { 3, 4 } },
 const = {
 pi = {
     int = 3 '\001',
     float = 3.14,
     str = "pi"
   },
   e = 2.718281828459045
 },
 array = {
   {
     elem_00 = 1,
     elem_01 = 2
   },
   {
     elem_10 = 3,
     elem_11 = 4
   }
 },
 tab3 = {3 <repeats 3 times>},
 tab4 = {{2 <repeats 2 times>} <repeats 5 times>},
 d = 4
}

 On utilise ensuite notre script Python :

flatten_gdb_dump.py
$ python -O flatten_gdb_dump.py sample.dump

Qui produit le flux suivant :

#nom_var;sizeof_var;val_ref;flag_verif[,comment]
a;0;1;1
b;0;2;1
c;0;3;1
tab[0];0;0;1
tab[1];0;1;1
tab[2];0;2;1
tab2[0][0];0;1;1
tab2[0][1];0;2;1
tab2[1][0];0;3;1
tab2[1][1];0;4;1
const.pi.int;0;3;1
const.pi.float;0;3.14;1
const.pi.str;2;pi;1
const.e;0;2.718281828459045;1
array[0].elem_00;0;1;1
array[0].elem_01;0;2;1
array[1].elem_10;0;3;1
array[1].elem_11;0;4;1
tab3[0];0;3;1
tab3[1];0;3;1
tab3[2];0;3;1
tab4[0][0];0;2;1
tab4[0][1];0;2;1
tab4[1][0];0;2;1
tab4[1][1];0;2;1
tab4[2][0];0;2;1
tab4[2][1];0;2;1
tab4[3][0];0;2;1
tab4[3][1];0;2;1
tab4[4][0];0;2;1
tab4[4][1];0;2;1
d;0;4;1

Et c’est gagné !

P.I. j’utilise le module pyparsing (en version 1.5.7 pour la ’vielle’ version 2.4.3 de Python que j’ai utilisé) ainsi que le module ordereddict (v1.1) pour profiter les dictionnaires ordonnés (non disponible en Python < 2.7).

pyparsing.py
ordereddict.py

P.S. j’ai quand même due ’patcher’ la lib pyparsing 1.5.7 afin d’utiliser les dictionnaires ordonnés (cela n’apparait dans pyparsing que depuis les collections dans Python 2.7).

CSV parser

Un autre parser de fichier, CSV cette fois-ci :

csv_parser.py