Tags

arm bin_sh blocage blosxom bsd bsdfrance cblog certification chroot cluster dg834 dhcp dns dnsmasq fail-over fail2ban firefox freebsd ftp git guruplug install ipv6 jail kernel kimsufi lex libre linutop makefile netbook netbsd nginx ntp ntp.org openntpd openrd openwrt proxy python reverse rmll route rrdcgi sl2009 ssd symon update usb var_empty vimperator world xen yacc zfs

Powered by

blOg
maRkdown
awK
shEll

14/11/2010

[ lex yacc ]

201011142003 lex yacc

lex et yacc, mes nouveaux copains

Depuis quelques temps (mais il remonte à quand mon dernier billet ?) je bosse à mes heures perdues sur un projet qui roxe. Ce projet utilise un fichier de configuration dont la syntaxe ressemble à ceci:

# comment
set key value

Rien de spécial. Là où ça se corse (comme on dit à Bastia), c'est quand, plutôt que de faire son parser avec ses petites mimines toutes crades et maladroites, on décide d'utiliser les bon outils. A ma droite lex, à ma gauche yacc. Mes deux nouveaux copains.

On ne peut pas dire qu'on croule sous la documentation, et je me suis largement inspiré de http://ds9a.nl/lex-yacc/cvs/lex-yacc-howto.html. Je me fends d'un billet, modeste contribution à ces outils qu'on utilise tous les jours sans le savoir.

On commence par définir notre fichier de configuration:

# set debug on|off
set debug on

# set user <login>
set user nobody

# set chroot /path/to/chroot
set chroot /tmp/chroot

Ne pas hésiter à bien commenter son fichier de conf', ça mange pas de pain. Petite analyse:

Mes nouveaux copains se partagent le boulot: un s'occupe de la syntaxe (token.l) pendant que l'autre s'occupe de la grammaire (parse.y). Pour ne pas transformer ce billet en série de listings indigestes, les tgz des différentes étapes sont disponibles ici.

Etape n°1:

dsx@itanium>tar xzvf step1.tgz 
x Makefile
x conf.conf
x main.c
x parse.y
x token.l
dsx@itanium>make && make check
set debug '1'
set chroot '/tmp/chroot'
set user 'nobody'

Etape n°2: contrôler les valeurs saisies. Un chroot nobody ou un user /tmp/ risque d'être du plus mauvais effet, je rajoute deux fonctions dans parse.y :

dsx@itanium>make clean && make && make check && make fail
set debug '1'
set chroot '/tmp/chroot'
set user 'nobody'
set debug '1'
parse_conf: '/if/this/file/exists/you/are/crazy': directory not exists

*** Error code 1

Stop in /tmp/for_rm.

Etape n°3: c'est bien joli ces printf, mais une structure correctement remplie ça serait mieux.

dsx@itanium>make clean && make && make check 
Dump config
    debug: '1'
    chroot: '/tmp/chroot'
    user: 'nobody'

Notre fichier de conf est un peu tristounet, on va rajouter un truc qui poutre:

set debug on
set user nobody
set chroot /tmp/chroot
color {
    blue
    white
    red
}

Etape n°4: autant le dire tout de suite, sys/queue.h ça aide. Beaucoup. Vraiment.

dsx@itanium>make clean && make && make check
Dump config
    debug: '1'
    chroot: '/tmp/chroot'
    user: 'nobody'
    couleurs
            'blue'
            'white'
            'red'

Pour les syntaxes un peu plus compliquées, ne pas hésiter à jouer des regexp et des fonctions d'affectation dans token.l.


Lien vers ce billet