From 16e0fd9d89ef433848678dfc8dd20426844a2868 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 29 Jan 2016 00:32:25 +0100
Subject: Cleaned, rewritten and improved the whole code of the compiler.

---
 .gitignore                   |    3 +
 ChangeLog                    |   72 +++
 configure.ac                 |    6 +
 tools/d2c/Makefile.am        |   49 +-
 tools/d2c/args.c             | 1244 ------------------------------------------
 tools/d2c/args.h             |  138 -----
 tools/d2c/args/Makefile.am   |   31 ++
 tools/d2c/args/decl.h        |   54 ++
 tools/d2c/args/grammar.y     |  191 +++++++
 tools/d2c/args/manager.c     | 1244 ++++++++++++++++++++++++++++++++++++++++++
 tools/d2c/args/manager.h     |  138 +++++
 tools/d2c/args/tokens.l      |   67 +++
 tools/d2c/bits.c             |  385 -------------
 tools/d2c/bits.h             |   87 ---
 tools/d2c/bits/Makefile.am   |   31 ++
 tools/d2c/bits/decl.h        |   37 ++
 tools/d2c/bits/grammar.y     |  117 ++++
 tools/d2c/bits/manager.c     |  383 +++++++++++++
 tools/d2c/bits/manager.h     |   87 +++
 tools/d2c/bits/tokens.l      |   33 ++
 tools/d2c/coder.c            |   23 +-
 tools/d2c/coder.h            |    9 +-
 tools/d2c/conv.c             |  518 ------------------
 tools/d2c/conv.h             |   94 ----
 tools/d2c/conv/Makefile.am   |   31 ++
 tools/d2c/conv/decl.h        |   37 ++
 tools/d2c/conv/grammar.y     |  130 +++++
 tools/d2c/conv/manager.c     |  518 ++++++++++++++++++
 tools/d2c/conv/manager.h     |   94 ++++
 tools/d2c/conv/tokens.l      |   32 ++
 tools/d2c/d2c.mk             |    2 +-
 tools/d2c/d2c_gram.y         |  472 ----------------
 tools/d2c/d2c_tok.l          |  235 --------
 tools/d2c/grammar.y          |  443 +++++++++++++++
 tools/d2c/helpers.h          |    6 +-
 tools/d2c/hooks.c            |  169 ------
 tools/d2c/hooks.h            |   51 --
 tools/d2c/hooks/Makefile.am  |   31 ++
 tools/d2c/hooks/decl.h       |   37 ++
 tools/d2c/hooks/grammar.y    |  109 ++++
 tools/d2c/hooks/manager.c    |  169 ++++++
 tools/d2c/hooks/manager.h    |   51 ++
 tools/d2c/hooks/tokens.l     |   26 +
 tools/d2c/manual.h           |   65 +++
 tools/d2c/pproc.h            |    6 +-
 tools/d2c/qckcall.h          |   13 +-
 tools/d2c/rules.c            |  531 ------------------
 tools/d2c/rules.h            |  120 ----
 tools/d2c/rules/Makefile.am  |   31 ++
 tools/d2c/rules/decl.h       |   37 ++
 tools/d2c/rules/grammar.y    |  162 ++++++
 tools/d2c/rules/manager.c    |  531 ++++++++++++++++++
 tools/d2c/rules/manager.h    |  120 ++++
 tools/d2c/rules/tokens.l     |   57 ++
 tools/d2c/spec.h             |   16 +-
 tools/d2c/syntax.c           |  385 -------------
 tools/d2c/syntax.h           |   73 ---
 tools/d2c/syntax/Makefile.am |   31 ++
 tools/d2c/syntax/decl.h      |   37 ++
 tools/d2c/syntax/grammar.y   |  109 ++++
 tools/d2c/syntax/manager.c   |  385 +++++++++++++
 tools/d2c/syntax/manager.h   |   73 +++
 tools/d2c/syntax/tokens.l    |   39 ++
 tools/d2c/tokens.l           |  132 +++++
 64 files changed, 6089 insertions(+), 4548 deletions(-)
 delete mode 100644 tools/d2c/args.c
 delete mode 100644 tools/d2c/args.h
 create mode 100644 tools/d2c/args/Makefile.am
 create mode 100644 tools/d2c/args/decl.h
 create mode 100644 tools/d2c/args/grammar.y
 create mode 100644 tools/d2c/args/manager.c
 create mode 100644 tools/d2c/args/manager.h
 create mode 100644 tools/d2c/args/tokens.l
 delete mode 100644 tools/d2c/bits.c
 delete mode 100644 tools/d2c/bits.h
 create mode 100644 tools/d2c/bits/Makefile.am
 create mode 100644 tools/d2c/bits/decl.h
 create mode 100644 tools/d2c/bits/grammar.y
 create mode 100644 tools/d2c/bits/manager.c
 create mode 100644 tools/d2c/bits/manager.h
 create mode 100644 tools/d2c/bits/tokens.l
 delete mode 100644 tools/d2c/conv.c
 delete mode 100644 tools/d2c/conv.h
 create mode 100644 tools/d2c/conv/Makefile.am
 create mode 100644 tools/d2c/conv/decl.h
 create mode 100644 tools/d2c/conv/grammar.y
 create mode 100644 tools/d2c/conv/manager.c
 create mode 100644 tools/d2c/conv/manager.h
 create mode 100644 tools/d2c/conv/tokens.l
 delete mode 100644 tools/d2c/d2c_gram.y
 delete mode 100644 tools/d2c/d2c_tok.l
 create mode 100644 tools/d2c/grammar.y
 delete mode 100644 tools/d2c/hooks.c
 delete mode 100644 tools/d2c/hooks.h
 create mode 100644 tools/d2c/hooks/Makefile.am
 create mode 100644 tools/d2c/hooks/decl.h
 create mode 100644 tools/d2c/hooks/grammar.y
 create mode 100644 tools/d2c/hooks/manager.c
 create mode 100644 tools/d2c/hooks/manager.h
 create mode 100644 tools/d2c/hooks/tokens.l
 create mode 100644 tools/d2c/manual.h
 delete mode 100644 tools/d2c/rules.c
 delete mode 100644 tools/d2c/rules.h
 create mode 100644 tools/d2c/rules/Makefile.am
 create mode 100644 tools/d2c/rules/decl.h
 create mode 100644 tools/d2c/rules/grammar.y
 create mode 100644 tools/d2c/rules/manager.c
 create mode 100644 tools/d2c/rules/manager.h
 create mode 100644 tools/d2c/rules/tokens.l
 delete mode 100644 tools/d2c/syntax.c
 delete mode 100644 tools/d2c/syntax.h
 create mode 100644 tools/d2c/syntax/Makefile.am
 create mode 100644 tools/d2c/syntax/decl.h
 create mode 100644 tools/d2c/syntax/grammar.y
 create mode 100644 tools/d2c/syntax/manager.c
 create mode 100644 tools/d2c/syntax/manager.h
 create mode 100644 tools/d2c/syntax/tokens.l
 create mode 100644 tools/d2c/tokens.l

diff --git a/.gitignore b/.gitignore
index f7ab09f..8461547 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,6 +33,9 @@ stamp-h1
 # Flex/Bison
 *_gram.[ch]
 *_tok.[ch]
+grammar.[ch]
+grammar.output
+tokens.[ch]
 ylwrap
 
 # i18n
diff --git a/ChangeLog b/ChangeLog
index e711c8b..ad88de4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,75 @@
+16-01-29  Cyrille Bagard <nocbos@gmail.com>
+
+	* .gitignore:
+	Update the names of files relative to Flex/Bison.
+
+	* configure.ac:
+	Extend the list of Makefiles used for d2c.
+
+	* tools/d2c/Makefile.am:
+	* tools/d2c/args.c:
+	* tools/d2c/args.h:
+	* tools/d2c/args/Makefile.am:
+	* tools/d2c/args/decl.h:
+	* tools/d2c/args/grammar.y:
+	* tools/d2c/args/manager.c:
+	* tools/d2c/args/manager.h:
+	* tools/d2c/args/tokens.l:
+	* tools/d2c/bits.c:
+	* tools/d2c/bits.h:
+	* tools/d2c/bits/Makefile.am:
+	* tools/d2c/bits/decl.h:
+	* tools/d2c/bits/grammar.y:
+	* tools/d2c/bits/manager.c:
+	* tools/d2c/bits/manager.h:
+	* tools/d2c/bits/tokens.l:
+	* tools/d2c/coder.c:
+	* tools/d2c/coder.h:
+	* tools/d2c/conv.c:
+	* tools/d2c/conv.h:
+	* tools/d2c/conv/Makefile.am:
+	* tools/d2c/conv/decl.h:
+	* tools/d2c/conv/grammar.y:
+	* tools/d2c/conv/manager.c:
+	* tools/d2c/conv/manager.h:
+	* tools/d2c/conv/tokens.l:
+	* tools/d2c/d2c.mk:
+	* tools/d2c/d2c_gram.y:
+	* tools/d2c/d2c_tok.l:
+	* tools/d2c/grammar.y:
+	* tools/d2c/helpers.h:
+	* tools/d2c/hooks.c:
+	* tools/d2c/hooks.h:
+	* tools/d2c/hooks/Makefile.am:
+	* tools/d2c/hooks/decl.h:
+	* tools/d2c/hooks/grammar.y:
+	* tools/d2c/hooks/manager.c:
+	* tools/d2c/hooks/manager.h:
+	* tools/d2c/hooks/tokens.l:
+	* tools/d2c/manual.h:
+	* tools/d2c/pproc.h:
+	* tools/d2c/qckcall.h:
+	* tools/d2c/rules.c:
+	* tools/d2c/rules.h:
+	* tools/d2c/rules/Makefile.am:
+	* tools/d2c/rules/decl.h:
+	* tools/d2c/rules/grammar.y:
+	* tools/d2c/rules/manager.c:
+	* tools/d2c/rules/manager.h:
+	* tools/d2c/rules/tokens.l:
+	* tools/d2c/spec.h:
+	* tools/d2c/syntax.c:
+	* tools/d2c/syntax.h:
+	* tools/d2c/syntax/Makefile.am:
+	* tools/d2c/syntax/decl.h:
+	* tools/d2c/syntax/grammar.y:
+	* tools/d2c/syntax/manager.c:
+	* tools/d2c/syntax/manager.h:
+	* tools/d2c/syntax/tokens.l:
+	* tools/d2c/tokens.l:
+	New/old/renamed/moved entries: clean, rewrite and improve the whole code
+	of the compiler.
+
 16-01-23  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/common/endianness.c:
diff --git a/configure.ac b/configure.ac
index d8896fd..1d61cc8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -359,6 +359,12 @@ AC_CONFIG_FILES([Makefile
                  src/plugins/overjump/Makefile
                  tools/Makefile
                  tools/d2c/Makefile
+                 tools/d2c/args/Makefile
+                 tools/d2c/bits/Makefile
+                 tools/d2c/conv/Makefile
+                 tools/d2c/hooks/Makefile
+                 tools/d2c/rules/Makefile
+                 tools/d2c/syntax/Makefile
                  themes/Makefile])
 
 AC_OUTPUT
diff --git a/tools/d2c/Makefile.am b/tools/d2c/Makefile.am
index 63ca5fe..e89384f 100644
--- a/tools/d2c/Makefile.am
+++ b/tools/d2c/Makefile.am
@@ -1,35 +1,46 @@
 
-BUILT_SOURCES = d2c-d2c_gram.h
+BUILT_SOURCES = grammar.h
+
+
+# On évite d'utiliser les variables personnalisées de type *_la_[YL]FLAGS
+# afin de conserver des noms de fichiers simples, ie sans le nom de la
+# bibliothèque de sortie en préfixe.
+
+AM_YFLAGS = -v -d -p d2c_
+
+AM_LFLAGS = -P d2c_ -o lex.yy.c --header-file=tokens.h			\
+			-Dyylval=d2c_lval -Dyyget_lineno=d2c_get_lineno 	\
+			-Dyy_scan_bytes=d2c__scan_bytes						\
+			-Dyy_delete_buffer=d2c__delete_buffer
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS)
 
-AM_YFLAGS = -d
 
 bin_PROGRAMS = d2c
 
+.NOTPARALLEL: $(bin_PROGRAMS)
 
 d2c_SOURCES =							\
-	args.h args.c						\
-	bits.h bits.c						\
 	coder.h coder.c						\
-	conv.h conv.c						\
-	d2c_tok.l							\
-	d2c_gram.y							\
+	tokens.l							\
+	grammar.y							\
 	helpers.h helpers.c					\
-	hooks.h hooks.c						\
+	manual.h							\
 	pproc.h pproc.c						\
 	qckcall.h qckcall.c					\
-	rules.h rules.c						\
-	spec.h spec.c						\
-	syntax.h syntax.c
+	spec.h spec.c
 
-d2c_YFLAGS = -v -d -p d2c_ -o y.tab.c
+d2c_LDADD =								\
+	bits/libd2cbits.la					\
+	conv/libd2cconv.la					\
+	hooks/libd2chooks.la				\
+	rules/libd2crules.la				\
+	syntax/libd2csyntax.la				\
+	args/libd2cargs.la
 
-d2c_LFLAGS = -P d2c_ --header-file=d2c_tok.h -o lex.yy.c
 
-
-AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
-
-AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS)
+# Automake fait les choses à moitié
+CLEANFILES = grammar.h grammar.c grammar.output tokens.c tokens.h
 
 
-# Automake fait les choses à moitié
-CLEANFILES = d2c_gram.h d2c_gram.c d2c-d2c_tok.c
+SUBDIRS = args bits conv hooks rules syntax
diff --git a/tools/d2c/args.c b/tools/d2c/args.c
deleted file mode 100644
index f933160..0000000
--- a/tools/d2c/args.c
+++ /dev/null
@@ -1,1244 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * args.c - gestion des arguments dans leur ensemble
- *
- * Copyright (C) 2015 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  OpenIDA is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  OpenIDA is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "args.h"
-
-
-#include <assert.h>
-#include <malloc.h>
-#include <string.h>
-
-
-#include "conv.h"
-#include "helpers.h"
-
-
-
-/* Types d'expressions représentés */
-typedef enum _ConvExprType
-{
-    CET_NAME,                               /* Désignation de variable     */
-    CET_NUMBER,                             /* Valeur codée en dur         */
-    CET_BINVAL,                             /* Valeur binaire bxxx         */
-    CET_HEXVAL,                             /* Valeur sous forme hexa.     */
-    CET_COMPOSED,                           /* Agrégat de champs divers    */
-    CET_UNARY,                              /* Opération unaire            */
-    CET_BINARY,                             /* Opération binaire           */
-
-    CET_COUNT
-
-} ConvExprType;
-
-
-/* Représentation d'une expression de conversion */
-struct _arg_expr_t
-{
-    ConvExprType type;
-
-    bool declared;                          /* Expression déjà déclarée ?  */
-    bool defined;                           /* Expression déjà définie ?   */
-
-    union
-    {
-        /* CET_NAME */
-        struct
-        {
-            char *original;                 /* Désignation non transformée */
-            char *name;                     /* Désignation de variable     */
-
-        };
-
-        /* CET_NUMBER */
-        unsigned long number;               /* Valeur durablement définie  */
-
-        /* CET_BINVAL */
-        char *binval;                       /* Valeur sous forme bxxx      */
-
-        /* CET_HEXVAL */
-        char *hexval;                       /* Valeur sous forme 0xxxx     */
-
-        /* CET_COMPOSED */
-        struct
-        {
-            char **comp_items;              /* Elements à agréger          */
-            size_t comp_count;              /* Quantité de ces éléments    */
-
-        };
-
-        /* CET_UNARY */
-        struct
-        {
-            arg_expr_t *un_expr;            /* Expression à traiter        */
-            ConvUnaryOperation un_op;       /* Type d'opération à mener    */
-
-        };
-
-        /* CET_BINARY */
-        struct
-        {
-            arg_expr_t *bin_expr1;          /* Expression à traiter        */
-            arg_expr_t *bin_expr2;          /* Expression à traiter        */
-            ConvBinaryOperation bin_op;     /* Type d'opération à mener    */
-
-        };
-
-    };
-
-};
-
-
-/* Visite une expression en traitant en premier ses composantes. */
-typedef bool (* visit_expr_fc) (arg_expr_t *, int, const coding_bits *, const conv_list *, void *);
-
-/* Visite une expression en traitant en premier ses composantes. */
-static bool visit_arg_expr(arg_expr_t *, visit_expr_fc, int, const coding_bits *, const conv_list *, void *);
-
-/* Retrouve si elle existe une variable manipulée. */
-static bool find_var_by_name(const coding_bits *, const conv_list *, const char *, raw_bitfield **, conv_func **);
-
-
-
-/* ----------------------- MANIPULATION DE LISTES D'ARGUMENTS ----------------------- */
-
-
-/* Liste d'expressions utilisées en arguments de conversion */
-struct _arg_list_t
-{
-    arg_expr_t **items;                     /* Liste d'expressions         */
-    size_t count;                           /* Taille de cette liste       */
-
-};
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                            REPRESENTATION D'UN ARGUMENT                            */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : name = désignation d'une variable quelconque.                *
-*                                                                             *
-*  Description : Référence une variable en tant qu'expression de conversion.  *
-*                                                                             *
-*  Retour      : Nouvelle expression mise en place.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-arg_expr_t *build_arg_expr_from_name(char *name)
-{
-    arg_expr_t *result;                     /* Structure à retourner       */
-
-    result = (arg_expr_t *)calloc(1, sizeof(arg_expr_t));
-
-    result->type = CET_NAME;
-
-    result->original = strdup(name);
-    result->name = make_string_lower(name);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : number = valeur à conserver dans sa forme brute.             *
-*                                                                             *
-*  Description : Conserve une valeur en tant qu'expression de conversion.     *
-*                                                                             *
-*  Retour      : Nouvelle expression mise en place.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-arg_expr_t *build_arg_expr_from_number(unsigned long number)
-{
-    arg_expr_t *result;                     /* Structure à retourner       */
-
-    result = (arg_expr_t *)calloc(1, sizeof(arg_expr_t));
-
-    result->type = CET_NUMBER;
-
-    result->number = number;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : binval = valeur binaire à conserver dans sa forme brute.     *
-*                                                                             *
-*  Description : Conserve une valeur en tant qu'expression de conversion.     *
-*                                                                             *
-*  Retour      : Nouvelle expression mise en place.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-arg_expr_t *build_arg_expr_from_binval(char *binval)
-{
-    arg_expr_t *result;                     /* Structure à retourner       */
-
-    result = (arg_expr_t *)calloc(1, sizeof(arg_expr_t));
-
-    result->type = CET_BINVAL;
-
-    result->binval = binval;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : number = valeur hexadécimale à conserver dans sa forme brute.*
-*                                                                             *
-*  Description : Conserve une valeur en tant qu'expression de conversion.     *
-*                                                                             *
-*  Retour      : Nouvelle expression mise en place.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-arg_expr_t *build_arg_expr_from_hexval(char *hexval)
-{
-    arg_expr_t *result;                     /* Structure à retourner       */
-
-    result = (arg_expr_t *)calloc(1, sizeof(arg_expr_t));
-
-    result->type = CET_HEXVAL;
-
-    result->hexval = hexval;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : item1 = premier élément à agréger.                           *
-*                item2 = second élément à agréger.                            *
-*                                                                             *
-*  Description : Construit une base d'expression de conversion composée.      *
-*                                                                             *
-*  Retour      : Nouvelle expression mise en place.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-arg_expr_t *build_composed_arg_expr(char *item1, char *item2)
-{
-    arg_expr_t *result;                     /* Structure à retourner       */
-
-    result = (arg_expr_t *)calloc(1, sizeof(arg_expr_t));
-
-    result->type = CET_COMPOSED;
-
-    result->comp_items = (char **)calloc(2, sizeof(char *));
-    result->comp_count = 2;
-
-    result->comp_items[0] = make_string_lower(item1);
-    result->comp_items[1] = make_string_lower(item2);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : expr = expression déjà en place à compléter.                 *
-*                item = nouvel élément à agréger.                             *
-*                                                                             *
-*  Description : Etend une base d'expression de conversion composée.          *
-*                                                                             *
-*  Retour      : Expression en place et mise à jour.                          *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-arg_expr_t *extend_composed_arg_expr(arg_expr_t *expr, char *item)
-{
-    assert(expr->type == CET_COMPOSED);
-
-    expr->comp_items = (char **)realloc(expr->comp_items, ++expr->comp_count * sizeof(char *));
-
-    expr->comp_items[expr->comp_count - 1] = make_string_lower(item);
-
-    return expr;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : expr = expression à encapsuler.                              *
-*                op   = opération unaire à associer à l'opération.            *
-*                                                                             *
-*  Description : Traduit une opération unaire sur expression de conversion.   *
-*                                                                             *
-*  Retour      : Nouvelle expression mise en place.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-arg_expr_t *build_unary_arg_expr(arg_expr_t *expr, ConvUnaryOperation op)
-{
-    arg_expr_t *result;                     /* Structure à retourner       */
-
-    result = (arg_expr_t *)calloc(1, sizeof(arg_expr_t));
-
-    result->type = CET_UNARY;
-
-    result->un_expr = expr;
-    result->un_op = op;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : expr1 = première expression à encapsuler.                    *
-*                expr2 = seconde expression à encapsuler.                     *
-*                op    = opération binaire à associer à l'opération.          *
-*                                                                             *
-*  Description : Traduit une opération binaire sur expression de conversion.  *
-*                                                                             *
-*  Retour      : Nouvelle expression mise en place.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-arg_expr_t *build_binary_arg_expr(arg_expr_t *expr1, arg_expr_t *expr2, ConvBinaryOperation op)
-{
-    arg_expr_t *result;                    /* Structure à retourner       */
-
-    result = (arg_expr_t *)calloc(1, sizeof(arg_expr_t));
-
-    result->type = CET_BINARY;
-
-    result->bin_expr1 = expr1;
-    result->bin_expr2 = expr2;
-    result->bin_op = op;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : expr = expression à libérer de la mémoire.                   *
-*                                                                             *
-*  Description : Supprime tous les éléments mis en place pour un argument.    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void delete_arg_expr(arg_expr_t *expr)
-{
-    size_t i;                               /* Boucle de parcours          */
-
-    switch (expr->type)
-    {
-        case CET_NAME:
-            free(expr->original);
-            free(expr->name);
-            break;
-
-        case CET_BINVAL:
-            free(expr->binval);
-            break;
-
-        case CET_HEXVAL:
-            free(expr->hexval);
-            break;
-
-        case CET_COMPOSED:
-            for (i = 0; i < expr->comp_count; i++)
-                free(expr->comp_items[i]);
-            free(expr->comp_items);
-            break;
-
-        case CET_UNARY:
-            delete_arg_expr(expr->un_expr);
-            break;
-
-        case CET_BINARY:
-            delete_arg_expr(expr->bin_expr1);
-            delete_arg_expr(expr->bin_expr2);
-            break;
-
-        default:
-            break;
-
-    }
-
-    free(expr);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : expr = première expression à consulter.                      *
-*                bits = gestionnaire des bits d'encodage.                     *
-*                list = liste de l'ensemble des fonctions de conversion.      *
-*                size = taille déterminée avec précision. [OUT]               *
-*                                                                             *
-*  Description : Détermine la taille en bits d'une expression donnée.         *
-*                                                                             *
-*  Retour      : true si la taille a pu être déterminée, false sinon.         *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool compute_arg_expr_size(const arg_expr_t *expr, const coding_bits *bits, const conv_list *list, unsigned int *size)
-{
-    bool result;                            /* Bilan à retourner           */
-    raw_bitfield *field;                    /* Eventuel champ brut associé */
-    conv_func *func;                        /* Eventuelle fonction liée    */
-    size_t i;                               /* Boucle de parcours          */
-    unsigned int tmp;                       /* Stockage temporaire         */
-
-    switch (expr->type)
-    {
-        case CET_NAME:
-
-            result = find_var_by_name(bits, list, expr->name, &field, &func);
-
-            if (result)
-            {
-                if (field != NULL)
-                    *size = get_raw_bitfield_length(field);
-                else
-                    result = compute_conv_func_size(func, bits, list, size);
-            }
-
-            /**
-             * On autorise le passage de constante inconnue par d2c mais valable pour gcc.
-             */
-            else result = true;
-
-            break;
-
-        case CET_COMPOSED:
-
-            result = true;
-            *size = 0;
-
-            for (i = 0; i < expr->comp_count && result; i++)
-            {
-                if (isdigit(expr->comp_items[i][0]))
-                    *size += strlen(expr->comp_items[i]);
-
-                else
-                {
-                    if (!find_var_by_name(bits, list, expr->comp_items[i], &field, &func))
-                        result = false;
-
-                    else
-                    {
-                        if (field != NULL)
-                            *size += get_raw_bitfield_length(field);
-                        else
-                        {
-                            result = compute_conv_func_size(func, bits, list, &tmp);
-                            *size += tmp;
-                        }
-                    }
-
-                }
-
-            }
-
-            break;
-
-        case CET_UNARY:
-            result = compute_arg_expr_size(expr->un_expr, bits, list, size);
-            break;
-
-        case CET_BINARY:
-
-            result = compute_arg_expr_size(expr->bin_expr1, bits, list, &tmp);
-
-            if (result)
-                result = compute_arg_expr_size(expr->bin_expr1, bits, list, size);
-
-            if (tmp > *size) *size = tmp;
-
-            break;
-
-        default:
-            result = false;
-            break;
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : expr = première expression à encapsuler.                     *
-*                fd   = descripteur d'un flux ouvert en écriture.             *
-*                bits = gestionnaire des bits d'encodage.                     *
-*                list = liste de l'ensemble des fonctions de conversion.      *
-*                data = éventuelle donnée à transmettre à chaque visite.      *
-*                                                                             *
-*  Description : Visite une expression en traitant en premier ses composantes.*
-*                                                                             *
-*  Retour      : Bilan des traitements effectués.                             *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool visit_arg_expr(arg_expr_t *expr, visit_expr_fc visit, int fd, const coding_bits *bits, const conv_list *list, void *data)
-{
-    bool result;                            /* Bilan à retourner           */
-
-    switch (expr->type)
-    {
-        case CET_UNARY:
-            result = visit_arg_expr(expr->un_expr, visit, fd, bits, list, data);
-            break;
-
-        case CET_BINARY:
-            result = visit_arg_expr(expr->bin_expr1, visit, fd, bits, list, data);
-            result = visit_arg_expr(expr->bin_expr2, visit, fd, bits, list, data);
-            break;
-
-        default:
-            result = true;
-            break;
-
-    }
-
-    result &= visit(expr, fd, bits, list, data);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : bits  = gestionnaire des bits d'encodage.                    *
-*                list  = liste de l'ensemble des fonctions de conversion.     *
-*                name  = déssignation de la variable recherchée.              *
-*                field = éventuel élement brut de décodage.                   *
-*                func  = éventuelle fonction de conversion pour intermédiaire.*
-*                                                                             *
-*  Description : Retrouve si elle existe une variable manipulée.              *
-*                                                                             *
-*  Retour      : Bilan des recherches : trouvaille ou non ?                   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool find_var_by_name(const coding_bits *bits, const conv_list *list, const char *name, raw_bitfield **field, conv_func **func)
-{
-    bool result;                            /* Bilan à retourner           */
-    raw_bitfield *cached_field;             /* Champ, version cachée       */
-    conv_func *cached_func;                 /* Fonction, version cachée    */
-
-    cached_field = find_named_field_in_bits(bits, name);
-    result = (cached_field != NULL);
-
-    if (!result)
-    {
-        cached_func = find_named_conv_in_list(list, name);
-        result = (cached_func != NULL);
-    }
-    else
-        cached_func = NULL;
-
-    if (field != NULL) *field = cached_field;
-    if (func != NULL) *func = cached_func;
-
-    if (!result)
-        fprintf(stderr, "Variable '%s' not found!\n", name);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : expr = première expression à encapsuler.                     *
-*                bits = gestionnaire des bits d'encodage.                     *
-*                list = liste de l'ensemble des fonctions de conversion.      *
-*                                                                             *
-*  Description : S'assure du marquage des expressions pre-requises.           *
-*                                                                             *
-*  Retour      : Bilan des traitements effectués.                             *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool ensure_arg_expr_content_fully_marked(arg_expr_t *expr, const coding_bits *bits, const conv_list *list)
-{
-    bool mark_sub_expr(arg_expr_t *sub, int dummy, const coding_bits *bts, const conv_list *lst, void *unused)
-    {
-        bool result;                        /* Bilan à retourner           */
-        size_t i;                           /* Boucle de parcours          */
-
-        bool mark_by_name(const coding_bits *_bts, const conv_list *_lst, const char *name)
-        {
-            bool found;                     /* Bilan d'opération à renvoyer*/
-            raw_bitfield *field;            /* Eventuel champ brut associé */
-            conv_func *func;                /* Eventuelle fonction liée    */
-
-            found = find_var_by_name(bts, lst, name, &field, &func);
-
-            if (found)
-            {
-                if (field != NULL)
-                    mark_raw_bitfield_as_used(field);
-                else /*if (func != NULL) */
-                    mark_conv_func(func, bts, lst);
-
-                printf(" VAR '%s' found (bf=%d  fc=%d)\n", name, !!field, !!func);
-
-
-            }
-            else printf(" VAR '%s' not found...\n", name);
-
-            return found;
-
-        }
-
-        /* Il est uniquement nécessaire de s'attacher aux références */
-        switch (sub->type)
-        {
-            case CET_NAME:
-                /* result = */mark_by_name(bits, lst, sub->name);
-                result = true;
-                break;
-
-            case CET_COMPOSED:
-                result = true;
-                for (i = 0; i < sub->comp_count && result; i++)
-                    if (!isdigit(sub->comp_items[i][0]))
-                        result = mark_by_name(bits, lst, sub->comp_items[i]);
-                break;
-
-            default:
-                result = true;
-                break;
-
-        }
-
-        return result;
-
-    }
-
-    return visit_arg_expr(expr, (visit_expr_fc)mark_sub_expr, -1, bits, list, NULL);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : expr = première expression à encapsuler.                     *
-*                fd   = descripteur d'un flux ouvert en écriture.             *
-*                arch = architecture visée par l'opération globale.           *
-*                bits = gestionnaire des bits d'encodage.                     *
-*                list = liste de l'ensemble des fonctions de conversion.      *
-*                wide = taille des mots décodés.                              *
-*                                                                             *
-*  Description : S'assure de la déclaration des expressions pre-requises.     *
-*                                                                             *
-*  Retour      : Bilan des traitements effectués.                             *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool ensure_arg_expr_content_fully_declared(arg_expr_t *expr, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide)
-{
-    bool declare_sub_expr(arg_expr_t *sub, int f, const coding_bits *bts, const conv_list *lst, unsigned int *wide)
-    {
-        bool result;                        /* Bilan à retourner           */
-        size_t i;                           /* Boucle de parcours          */
-
-        /* Si l'expression a déjà été définie lors d'un précédent besoin... */
-        printf("  sub declared ? %d  --  type = %d\n", sub->declared, sub->type);
-        if (sub->declared) return true;
-
-        bool declare_by_name(int _f, const coding_bits *_bts, const conv_list *_lst, unsigned int _wide, const char *name)
-        {
-            bool found;                     /* Bilan d'opération à renvoyer*/
-            conv_func *func;                /* Eventuelle fonction liée    */
-
-            found = find_var_by_name(bts, lst, name, NULL, &func);
-
-            if (found && func != NULL)
-            {
-                printf("========= DECLARE for '%s'\n", name);
-                found = declare_conv_func(func, _f, _bts, _lst, _wide);
-                printf("========= END DECLARE for '%s'\n", name);
-
-                /**
-                 * Si on déclare les variables suivantes dans declare_conv_func(),
-                 * elles seront également déclarées pour les fonctions de conversion
-                 * racine à partir de declare_syntax_items(), ce qui ne convient pas
-                 * car les appels racine servent directement d'arguments.
-                 */
-
-                if (is_conv_func_expression(func))
-                    dprintf(_f, "\t\tuint%u_t val_%s; // Ho\n", _wide, name);
-                else
-                    dprintf(_f, "\t\tGArchOperand *val_%s;;;;;\n", name);
-
-            }
-
-            return found;
-
-        }
-
-        /* Il est uniquement nécessaire de s'attacher aux références */
-        switch (sub->type)
-        {
-            case CET_NAME:
-                /* result = */declare_by_name(f, bits, lst, *wide, sub->name);
-                result = true;
-                break;
-
-            case CET_COMPOSED:
-                result = true;
-                for (i = 0; i < sub->comp_count && result; i++)
-                    if (!isdigit(sub->comp_items[i][0]))
-                        printf("... trying to declare... '%s'\n", sub->comp_items[i]);
-                for (i = 0; i < sub->comp_count && result; i++)
-                    if (!isdigit(sub->comp_items[i][0]))
-                        result = declare_by_name(f, bits, lst, *wide, sub->comp_items[i]);
-                break;
-
-            default:
-                result = true;
-                break;
-
-        }
-
-        sub->declared = result;
-
-        return result;
-
-    }
-
-    return visit_arg_expr(expr, (visit_expr_fc)declare_sub_expr, fd, bits, list, &wide);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : expr = première expression à encapsuler.                     *
-*                fd   = descripteur d'un flux ouvert en écriture.             *
-*                arch = architecture visée par l'opération globale.           *
-*                bits = gestionnaire des bits d'encodage.                     *
-*                list = liste de l'ensemble des fonctions de conversion.      *
-*                pp   = pré-processeur pour les échanges de chaînes.          *
-*                                                                             *
-*  Description : S'assure de la définition des expressions pre-requises.      *
-*                                                                             *
-*  Retour      : Bilan des traitements effectués.                             *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool ensure_arg_expr_content_fully_defined(arg_expr_t *expr, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp)
-{
-    typedef struct _def_info
-    {
-        const char *arch;
-        const pre_processor *pp;
-
-    } def_info;
-
-    def_info info;                          /* Transmissions au visiteur   */
-
-    bool define_sub_expr(arg_expr_t *sub, int f, const coding_bits *bts, const conv_list *lst, def_info *info)
-    {
-        bool result;                        /* Bilan à retourner           */
-        size_t i;                           /* Boucle de parcours          */
-
-        /* Si l'expression a déjà été définie lors d'un précédent besoin... */
-        if (sub->defined) return true;
-
-        bool define_by_name(int _f, const coding_bits *_bts, const conv_list *_lst, def_info *_info, const char *name)
-        {
-            bool found;                     /* Bilan d'opération à renvoyer*/
-            conv_func *func;                /* Eventuelle fonction liée    */
-
-            found = find_var_by_name(bts, lst, name, NULL, &func);
-
-            if (found && func != NULL)
-                found = define_conv_func(func, false, false, _f, _info->arch, _bts, _lst, _info->pp);
-
-            return found;
-
-        }
-
-        /* Il est uniquement nécessaire de s'attacher aux références */
-        switch (sub->type)
-        {
-            case CET_NAME:
-                /* result = */define_by_name(f, bits, lst, info, sub->name);
-                result = true;
-                break;
-
-            case CET_COMPOSED:
-                result = true;
-                for (i = 0; i < sub->comp_count && result; i++)
-                    if (!isdigit(sub->comp_items[i][0]))
-                        result = define_by_name(f, bits, lst, info, sub->comp_items[i]);
-                break;
-
-            default:
-                result = true;
-                break;
-
-        }
-
-        sub->defined = result;
-
-        return result;
-
-    }
-
-    info.arch = arch;
-    info.pp = pp;
-
-    return visit_arg_expr(expr, (visit_expr_fc)define_sub_expr, fd, bits, list, &info);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : expr = première expression à encapsuler.                     *
-*                fd   = descripteur d'un flux ouvert en écriture.             *
-*                bits = gestionnaire des bits d'encodage.                     *
-*                list = liste de l'ensemble des fonctions de conversion.      *
-*                                                                             *
-*  Description : Définit une expression utilisée dans une conversion.         *
-*                                                                             *
-*  Retour      : Bilan des traitements effectués.                             *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool define_arg_expr(const arg_expr_t *expr, int fd, const coding_bits *bits, const conv_list *list)
-{
-    bool result;                            /* Bilan à retourner           */
-    raw_bitfield *field;                    /* Eventuel champ brut associé */
-    conv_func *func;                        /* Eventuelle fonction liée    */
-    unsigned int max_size;                  /* Quantité de bits totale     */
-    size_t i;                               /* Boucle de parcours          */
-    const char *cname;                      /* Raccourci de confort        */
-    unsigned int used_size;                 /* Quantité de bits utilisée   */
-
-    result = true;
-
-    switch (expr->type)
-    {
-        case CET_NAME:
-
-            if (!find_var_by_name(bits, list, expr->name, &field, &func))
-                dprintf(fd, "%s", expr->original);
-
-            else
-            {
-                if (field != NULL)
-                    dprintf(fd, "raw_%s", expr->name);
-                else
-                    dprintf(fd, "val_%s", expr->name);
-            }
-
-            break;
-
-        case CET_NUMBER:
-            dprintf(fd, "%lu", expr->number);
-            break;
-
-        case CET_BINVAL:
-            dprintf(fd, "b%s", expr->binval);
-            break;
-
-        case CET_HEXVAL:
-            dprintf(fd, "0x%s", expr->hexval);
-            break;
-
-        case CET_COMPOSED:
-
-            result = compute_arg_expr_size(expr, bits, list, &max_size);
-
-            printf("MAX SIZE :: %u\n", max_size);
-
-            for (i = 0; i < expr->comp_count && result; i++)
-            {
-                cname = expr->comp_items[i];
-
-                if (i > 0)
-                    dprintf(fd, " | ");
-
-                /* Constante binaire ? */
-                if (isdigit(cname[0]))
-                {
-                    max_size -= strlen(cname);
-
-                    if (max_size == 0)
-                        dprintf(fd, "b%s", cname);
-                    else
-                        dprintf(fd, "b%s << %u", cname, max_size);
-
-                }
-
-                /* Ou variable définie ? */
-                else
-                {
-                    result = find_var_by_name(bits, list, cname, &field, &func);
-
-                    if (result)
-                    {
-                        if (field != NULL)
-                            used_size = get_raw_bitfield_length(field);
-                        else
-                            /*result = */compute_conv_func_size(func, bits, list, &used_size);
-
-                        max_size -= used_size;
-
-                        if (field != NULL)
-                        {
-                            if (max_size == 0)
-                                dprintf(fd, "raw_%s", cname);
-                            else
-                                dprintf(fd, "raw_%s << %u", cname, max_size);
-                        }
-                        else
-                        {
-                            if (max_size == 0)
-                                dprintf(fd, "val_%s", cname);
-                            else
-                                dprintf(fd, "val_%s << %u", cname, max_size);
-                        }
-
-                    }
-
-                }
-
-            }
-
-            break;
-
-        case CET_UNARY:
-
-            switch (expr->un_op)
-            {
-                case CUO_NOT:
-                    dprintf(fd, "!");
-                    break;
-                default:
-                    result = false;
-                    break;
-            }
-
-            result &= define_arg_expr(expr->un_expr, fd, bits, list);
-
-            break;
-
-        case CET_BINARY:
-
-            dprintf(fd, "(");
-
-            result = define_arg_expr(expr->bin_expr1, fd, bits, list);
-
-            switch (expr->bin_op)
-            {
-                case CBO_AND:
-                    dprintf(fd, " & ");
-                    break;
-                case CBO_EOR:
-                    dprintf(fd, " ^ ");
-                    break;
-                default:
-                    result = false;
-                    break;
-            }
-
-            result &= define_arg_expr(expr->bin_expr2, fd, bits, list);
-
-            dprintf(fd, ")");
-
-            break;
-
-        default:
-            result = false;
-            break;
-
-    }
-
-    return result;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                         MANIPULATION DE LISTES D'ARGUMENTS                         */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : expr = expression initial pour constituer une liste.         *
-*                                                                             *
-*  Description : Crée une liste d'arguments de conversion.                    *
-*                                                                             *
-*  Retour      : Nouvelle structure mise en place.                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-arg_list_t *build_arg_list(arg_expr_t *expr)
-{
-    arg_list_t *result;                     /* Structure à retourner       */
-
-    result = (arg_list_t *)calloc(1, sizeof(arg_list_t));
-
-    result->items = (arg_expr_t **)calloc(1, sizeof(arg_expr_t *));
-    result->count = 1;
-
-    result->items[0] = expr;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : list = liste d'expressions à supprimer de la mémoire.        *
-*                                                                             *
-*  Description : Libère la mémoire occupée par une liste d'expressions.       *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void delete_arg_list(arg_list_t *list)
-{
-    size_t i;                               /* Boucle de parcours          */
-
-    for (i = 0; i < list->count; i++)
-        delete_arg_expr(list->items[i]);
-
-    if (list->items != NULL)
-        free(list->items);
-
-    free(list);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : list = liste d'expressions à supprimer de la mémoire. [OUT]  *
-*                expr = expression à ajouter à la liste courante.             *
-*                                                                             *
-*  Description : Ajoute un élément à une liste d'arguments de conversion.     *
-*                                                                             *
-*  Retour      : Structure en place mise à jour.                              *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-arg_list_t *extend_arg_list(arg_list_t *list, arg_expr_t *expr)
-{
-    list->items = (arg_expr_t **)realloc(list->items, ++list->count * sizeof(arg_expr_t *));
-
-    list->items[list->count - 1] = expr;
-
-    return list;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : args = liste d'expressions à supprimer de la mémoire.        *
-*                bits = gestionnaire des bits d'encodage.                     *
-*                list = liste de l'ensemble des fonctions de conversion.      *
-*                                                                             *
-*  Description : S'assure du marquage des expressions pre-requises.           *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool ensure_arg_list_content_fully_marked(arg_list_t *args, const coding_bits *bits, const conv_list *list)
-{
-    bool result;                            /* Bilan à remonter            */
-    size_t i;                               /* Boucle de parcours          */
-
-    result = true;
-
-    for (i = 0; i < args->count && result; i++)
-        result = ensure_arg_expr_content_fully_marked(args->items[i], bits, list);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : args = liste d'expressions à supprimer de la mémoire.        *
-*                fd   = descripteur d'un flux ouvert en écriture.             *
-*                bits = gestionnaire des bits d'encodage.                     *
-*                list = liste de l'ensemble des fonctions de conversion.      *
-*                wide = taille des mots décodés.                              *
-*                                                                             *
-*  Description : S'assure de la déclaration des expressions pre-requises.     *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool ensure_arg_list_content_fully_declared(arg_list_t *args, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide)
-{
-    bool result;                            /* Bilan à remonter            */
-    size_t i;                               /* Boucle de parcours          */
-
-    result = true;
-
-    for (i = 0; i < args->count && result; i++)
-        result = ensure_arg_expr_content_fully_declared(args->items[i], fd, bits, list, wide);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : args = liste d'expressions à supprimer de la mémoire.        *
-*                fd   = descripteur d'un flux ouvert en écriture.             *
-*                arch = architecture visée par l'opération globale.           *
-*                bits = gestionnaire des bits d'encodage.                     *
-*                list = liste de l'ensemble des fonctions de conversion.      *
-*                pp   = pré-processeur pour les échanges de chaînes.          *
-*                                                                             *
-*  Description : S'assure de la définition des expressions pre-requises.      *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool ensure_arg_list_content_fully_defined(arg_list_t *args, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp)
-{
-    bool result;                            /* Bilan à remonter            */
-    size_t i;                               /* Boucle de parcours          */
-
-    result = true;
-
-    for (i = 0; i < args->count && result; i++)
-        result = ensure_arg_expr_content_fully_defined(args->items[i], fd, arch, bits, list, pp);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : args = liste d'expressions à supprimer de la mémoire.        *
-*                fd   = descripteur d'un flux ouvert en écriture.             *
-*                bits = gestionnaire des bits d'encodage.                     *
-*                list = liste de l'ensemble des fonctions de conversion.      *
-*                                                                             *
-*  Description : Définit les variables associées à un appel de fonction.      *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool define_arg_list(const arg_list_t *args, int fd, const coding_bits *bits, const conv_list *list)
-{
-    bool result;                            /* Bilan à remonter            */
-    size_t i;                               /* Boucle de parcours          */
-
-    result = true;
-
-    for (i = 0; i < args->count && result; i++)
-    {
-        if (i > 0) dprintf(fd, ", ");
-        result = define_arg_expr(args->items[i], fd, bits, list);
-    }
-
-    return result;
-
-}
diff --git a/tools/d2c/args.h b/tools/d2c/args.h
deleted file mode 100644
index b9f210b..0000000
--- a/tools/d2c/args.h
+++ /dev/null
@@ -1,138 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * args.h - prototypes pour la gestion des arguments dans leur ensemble
- *
- * Copyright (C) 2015 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  OpenIDA is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  OpenIDA is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _TOOLS_ARGS_H
-#define _TOOLS_ARGS_H
-
-
-#include "bits.h"
-#include "pproc.h"
-
-
-/* Liste des fonctions de conversions présentes */
-typedef struct _conv_list conv_list;
-
-
-
-/* -------------------------- REPRESENTATION D'UN ARGUMENT -------------------------- */
-
-
-/* Types d'opérations unaires */
-typedef enum _ConvUnaryOperation
-{
-    CUO_NOT,                                /* NOT (booléen)               */
-
-    CUO_COUNT
-
-} ConvUnaryOperation;
-
-/* Types d'opérations binaires */
-typedef enum _ConvBinaryOperation
-{
-    CBO_AND,                                /* Et logique                  */
-    CBO_EOR,                                /* Ou exclusif (booléen)       */
-
-    CBO_COUNT
-
-} ConvBinaryOperation;
-
-
-/* Représentation d'une expression de conversion */
-typedef struct _arg_expr_t arg_expr_t;
-
-
-/* Référence une variable en tant qu'expression de conversion. */
-arg_expr_t *build_arg_expr_from_name(char *);
-
-/* Conserve une valeur en tant qu'expression de conversion. */
-arg_expr_t *build_arg_expr_from_number(unsigned long );
-
-/* Conserve une valeur en tant qu'expression de conversion. */
-arg_expr_t *build_arg_expr_from_binval(char *);
-
-/* Conserve une valeur en tant qu'expression de conversion. */
-arg_expr_t *build_arg_expr_from_hexval(char *);
-
-/* Construit une base d'expression de conversion composée. */
-arg_expr_t *build_composed_arg_expr(char *, char *);
-
-/* Etend une base d'expression de conversion composée. */
-arg_expr_t *extend_composed_arg_expr(arg_expr_t *, char *);
-
-/* Traduit une opération unaire sur expression de conversion. */
-arg_expr_t *build_unary_arg_expr(arg_expr_t *, ConvUnaryOperation);
-
-/* Traduit une opération binaire sur expression de conversion. */
-arg_expr_t *build_binary_arg_expr(arg_expr_t *, arg_expr_t *, ConvBinaryOperation);
-
-/* Supprime tous les éléments mis en place pour un argument. */
-void delete_arg_expr(arg_expr_t *);
-
-/* Détermine la taille en bits d'une expression donnée. */
-bool compute_arg_expr_size(const arg_expr_t *, const coding_bits *, const conv_list *, unsigned int *);
-
-/* S'assure du marquage des expressions pre-requises. */
-bool ensure_arg_expr_content_fully_marked(arg_expr_t *, const coding_bits *, const conv_list *);
-
-/* S'assure de la déclaration des expressions pre-requises. */
-bool ensure_arg_expr_content_fully_declared(arg_expr_t *, int, const coding_bits *, const conv_list *, unsigned int);
-
-/* S'assure de la définition des expressions pre-requises. */
-bool ensure_arg_expr_content_fully_defined(arg_expr_t *, int, const char *, const coding_bits *, const conv_list *, const pre_processor *);
-
-/* Définit une expression utilisée dans une conversion. */
-bool define_arg_expr(const arg_expr_t *, int, const coding_bits *, const conv_list *);
-
-
-
-/* ----------------------- MANIPULATION DE LISTES D'ARGUMENTS ----------------------- */
-
-
-/* Liste d'expressions utilisées en arguments de conversion */
-typedef struct _arg_list_t arg_list_t;
-
-
-/* Crée une liste d'arguments de conversion. */
-arg_list_t *build_arg_list(arg_expr_t *);
-
-/* Libère la mémoire occupée par une liste d'expressions. */
-void delete_arg_list(arg_list_t *);
-
-/* Ajoute un élément à une liste d'arguments de conversion. */
-arg_list_t *extend_arg_list(arg_list_t *, arg_expr_t *);
-
-/* S'assure du marquage des expressions pre-requises. */
-bool ensure_arg_list_content_fully_marked(arg_list_t *, const coding_bits *, const conv_list *);
-
-/* S'assure de la déclaration des expressions pre-requises. */
-bool ensure_arg_list_content_fully_declared(arg_list_t *, int, const coding_bits *, const conv_list *, unsigned int);
-
-/* S'assure de la définition des expressions pre-requises. */
-bool ensure_arg_list_content_fully_defined(arg_list_t *, int, const char *, const coding_bits *, const conv_list *, const pre_processor *);
-
-/* Définit les variables associées à un appel de fonction. */
-bool define_arg_list(const arg_list_t *, int, const coding_bits *, const conv_list *);
-
-
-
-#endif  /* _TOOLS_ARGS_H */
diff --git a/tools/d2c/args/Makefile.am b/tools/d2c/args/Makefile.am
new file mode 100644
index 0000000..2a4cb4d
--- /dev/null
+++ b/tools/d2c/args/Makefile.am
@@ -0,0 +1,31 @@
+
+BUILT_SOURCES = grammar.h
+
+
+# On évite d'utiliser les variables personnalisées de type *_la_[YL]FLAGS
+# afin de conserver des noms de fichiers simples, ie sans le nom de la
+# bibliothèque de sortie en préfixe.
+
+AM_YFLAGS = -v -d -p args_
+
+AM_LFLAGS = -P args_ -o lex.yy.c --header-file=tokens.h			\
+			-Dyylval=args_lval -Dyyget_lineno=args_get_lineno 	\
+			-Dyy_scan_string=args__scan_string					\
+			-Dyy_delete_buffer=args__delete_buffer
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS)
+
+
+noinst_LTLIBRARIES  = libd2cargs.la
+
+.NOTPARALLEL: $(noinst_LTLIBRARIES)
+
+libd2cargs_la_SOURCES =					\
+	decl.h								\
+	manager.h manager.c					\
+	tokens.l							\
+	grammar.y
+
+
+# Automake fait les choses à moitié
+CLEANFILES = grammar.h grammar.c grammar.output tokens.c tokens.h
diff --git a/tools/d2c/args/decl.h b/tools/d2c/args/decl.h
new file mode 100644
index 0000000..8d64eaa
--- /dev/null
+++ b/tools/d2c/args/decl.h
@@ -0,0 +1,54 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * decl.h - déclarations de prototypes utiles
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _TOOLS_D2C_ARGS_DECL_H
+#define _TOOLS_D2C_ARGS_DECL_H
+
+
+#include "manager.h"
+
+
+
+/* Encapsulation de réponses multiples */
+typedef struct _right_op_t
+{
+    char *func;                             /* Eventuelle fonction d'appel */
+
+    union
+    {
+        arg_list_t *args;                   /* Liste d'arguments           */
+        arg_expr_t *expr;                   /* Argument multi-usages       */
+    };
+
+} right_op_t;
+
+
+/* Interprête des données relatives un opérande de droite. */
+bool load_args_from_raw_line(right_op_t *, const char *);
+
+/* Interprête des données relatives à un appel avec arguments. */
+bool load_call_from_raw_line(right_op_t *, const char *);
+
+
+
+#endif  /* _TOOLS_D2C_ARGS_DECL_H */
diff --git a/tools/d2c/args/grammar.y b/tools/d2c/args/grammar.y
new file mode 100644
index 0000000..6477c47
--- /dev/null
+++ b/tools/d2c/args/grammar.y
@@ -0,0 +1,191 @@
+
+%{
+
+#include "tokens.h"
+
+
+/* Affiche un message d'erreur suite à l'analyse en échec. */
+static int yyerror(right_op_t *, unsigned int *, char *);
+
+
+%}
+
+
+%code requires {
+
+#include "decl.h"
+
+}
+
+
+%union {
+
+    right_op_t operand;                     /* Construction finale         */
+
+    char *string;                           /* Chaîne de caractères        */
+    int integer;                            /* Valeur numérique entière    */
+
+    arg_list_t *args;                       /* Liste d'arguments           */
+    arg_expr_t *arg;                        /* Argument multi-usages       */
+    ConvUnaryOperation un_op;               /* Opération unaire            */
+    ConvBinaryOperation bin_op;             /* Opération bianire           */
+
+}
+
+
+%define api.pure full
+
+%parse-param { right_op_t *operand } { unsigned int *init_token }
+%lex-param { unsigned int *init_token }
+
+%code provides {
+
+#define YY_DECL \
+    int args_lex(YYSTYPE *yylvalp, unsigned int *init_token)
+
+YY_DECL;
+
+}
+
+
+%token FORCE_EXPR FORCE_CALL ALLOW_ALL
+%token NAME
+%token NUMBER BINVAL HEXVAL
+%token COMMA COLON OP CP
+%token NOT AND_LOG EOR
+
+
+%type <string> NAME
+%type <integer> NUMBER
+%type <string> BINVAL HEXVAL
+
+%type <operand> call
+%type <args> arg_list
+%type <arg> arg_expr arg_composed
+%type <un_op> arg_expr_un_op
+%type <bin_op> arg_expr_bin_op
+%type <string> arg_field
+
+
+%%
+
+
+right_op : FORCE_EXPR arg_expr  { operand->func = NULL; operand->expr = $2; }
+         | FORCE_CALL call      { *operand = $2; }
+         | arg_expr             { operand->func = NULL; operand->expr = $1; }
+         | call                 { *operand = $1; }
+
+call : NAME OP arg_list CP { $$.func = $1; $$.args = $3; }
+
+arg_list : arg_expr                { $$ = build_arg_list($1); }
+         | arg_list COMMA arg_expr { $$ = extend_arg_list($1, $3); }
+
+arg_expr : NAME                                     { $$ = build_arg_expr_from_name($1); }
+          | NUMBER                                  { $$ = build_arg_expr_from_number($1); }
+          | BINVAL                                  { $$ = build_arg_expr_from_binval($1); }
+          | HEXVAL                                  { $$ = build_arg_expr_from_hexval($1); }
+          | arg_composed                            { $$ = $1; }
+          | OP arg_expr CP                          { $$ = $2; }
+          | arg_expr_un_op arg_expr                 { $$ = build_unary_arg_expr($2, $1); }
+          | arg_expr arg_expr_bin_op arg_expr       { $$ = build_binary_arg_expr($1, $3, $2); }
+
+arg_expr_un_op : NOT { $$ = CUO_NOT; }
+
+arg_expr_bin_op : AND_LOG { $$ = CBO_AND; }
+                | EOR { $$ = CBO_EOR; }
+
+arg_composed : arg_field COLON arg_field    { $$ = build_composed_arg_expr($1, $3); }
+             | arg_composed COLON arg_field { $$ = extend_composed_arg_expr($1, $3); }
+
+arg_field : NAME   { $$ = $1; }
+          | BINVAL { $$ = $1; }
+
+
+%%
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand    = structure impliquée dans le processus.          *
+*                init_token = éventuel jeton d'initialisation ou NULL.        *
+*                msg        = message d'erreur.                               *
+*                                                                             *
+*  Description : Affiche un message d'erreur suite à l'analyse en échec.      *
+*                                                                             *
+*  Retour      : 0                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int yyerror(right_op_t *operand, unsigned int *init_token, char *msg)
+{
+	printf("args yyerror line %d: %s\n", yyget_lineno(), msg);
+
+	return 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = structure à constituer à partir de données lues.   *
+*                raw     = données brutes à analyser.                         *
+*                                                                             *
+*  Description : Interprête des données relatives un opérande de droite.      *
+*                                                                             *
+*  Retour      : true si l'opération s'est bien déroulée, false sinon.        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool load_args_from_raw_line(right_op_t *operand, const char *raw)
+{
+    bool result;                            /* Bilan à faire remonter      */
+    YY_BUFFER_STATE state;                  /* Support d'analyse           */
+    int status;                             /* Bilan de l'analyse          */
+
+    state = yy_scan_string(raw);
+
+    status = yyparse(operand, (unsigned int []) { ALLOW_ALL });
+
+    result = (status == 0);
+
+    yy_delete_buffer(state);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : operand = structure à constituer à partir de données lues.   *
+*                raw     = données brutes à analyser.                         *
+*                                                                             *
+*  Description : Interprête des données relatives à un appel avec arguments.  *
+*                                                                             *
+*  Retour      : true si l'opération s'est bien déroulée, false sinon.        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool load_call_from_raw_line(right_op_t *operand, const char *raw)
+{
+    bool result;                            /* Bilan à faire remonter      */
+    YY_BUFFER_STATE state;                  /* Support d'analyse           */
+    int status;                             /* Bilan de l'analyse          */
+
+    state = yy_scan_string(raw);
+
+    status = yyparse(operand, (unsigned int []) { FORCE_CALL });
+
+    result = (status == 0);
+
+    yy_delete_buffer(state);
+
+    return result;
+
+}
diff --git a/tools/d2c/args/manager.c b/tools/d2c/args/manager.c
new file mode 100644
index 0000000..ce300e6
--- /dev/null
+++ b/tools/d2c/args/manager.c
@@ -0,0 +1,1244 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * manager.c - gestion des arguments dans leur ensemble
+ *
+ * Copyright (C) 2015 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "manager.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+#include <string.h>
+
+
+#include "../helpers.h"
+#include "../conv/manager.h"
+
+
+
+/* Types d'expressions représentés */
+typedef enum _ConvExprType
+{
+    CET_NAME,                               /* Désignation de variable     */
+    CET_NUMBER,                             /* Valeur codée en dur         */
+    CET_BINVAL,                             /* Valeur binaire bxxx         */
+    CET_HEXVAL,                             /* Valeur sous forme hexa.     */
+    CET_COMPOSED,                           /* Agrégat de champs divers    */
+    CET_UNARY,                              /* Opération unaire            */
+    CET_BINARY,                             /* Opération binaire           */
+
+    CET_COUNT
+
+} ConvExprType;
+
+
+/* Représentation d'une expression de conversion */
+struct _arg_expr_t
+{
+    ConvExprType type;
+
+    bool declared;                          /* Expression déjà déclarée ?  */
+    bool defined;                           /* Expression déjà définie ?   */
+
+    union
+    {
+        /* CET_NAME */
+        struct
+        {
+            char *original;                 /* Désignation non transformée */
+            char *name;                     /* Désignation de variable     */
+
+        };
+
+        /* CET_NUMBER */
+        unsigned long number;               /* Valeur durablement définie  */
+
+        /* CET_BINVAL */
+        char *binval;                       /* Valeur sous forme bxxx      */
+
+        /* CET_HEXVAL */
+        char *hexval;                       /* Valeur sous forme 0xxxx     */
+
+        /* CET_COMPOSED */
+        struct
+        {
+            char **comp_items;              /* Elements à agréger          */
+            size_t comp_count;              /* Quantité de ces éléments    */
+
+        };
+
+        /* CET_UNARY */
+        struct
+        {
+            arg_expr_t *un_expr;            /* Expression à traiter        */
+            ConvUnaryOperation un_op;       /* Type d'opération à mener    */
+
+        };
+
+        /* CET_BINARY */
+        struct
+        {
+            arg_expr_t *bin_expr1;          /* Expression à traiter        */
+            arg_expr_t *bin_expr2;          /* Expression à traiter        */
+            ConvBinaryOperation bin_op;     /* Type d'opération à mener    */
+
+        };
+
+    };
+
+};
+
+
+/* Visite une expression en traitant en premier ses composantes. */
+typedef bool (* visit_expr_fc) (arg_expr_t *, int, const coding_bits *, const conv_list *, void *);
+
+/* Visite une expression en traitant en premier ses composantes. */
+static bool visit_arg_expr(arg_expr_t *, visit_expr_fc, int, const coding_bits *, const conv_list *, void *);
+
+/* Retrouve si elle existe une variable manipulée. */
+static bool find_var_by_name(const coding_bits *, const conv_list *, const char *, raw_bitfield **, conv_func **);
+
+
+
+/* ----------------------- MANIPULATION DE LISTES D'ARGUMENTS ----------------------- */
+
+
+/* Liste d'expressions utilisées en arguments de conversion */
+struct _arg_list_t
+{
+    arg_expr_t **items;                     /* Liste d'expressions         */
+    size_t count;                           /* Taille de cette liste       */
+
+};
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                            REPRESENTATION D'UN ARGUMENT                            */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : name = désignation d'une variable quelconque.                *
+*                                                                             *
+*  Description : Référence une variable en tant qu'expression de conversion.  *
+*                                                                             *
+*  Retour      : Nouvelle expression mise en place.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+arg_expr_t *build_arg_expr_from_name(char *name)
+{
+    arg_expr_t *result;                     /* Structure à retourner       */
+
+    result = (arg_expr_t *)calloc(1, sizeof(arg_expr_t));
+
+    result->type = CET_NAME;
+
+    result->original = strdup(name);
+    result->name = make_string_lower(name);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : number = valeur à conserver dans sa forme brute.             *
+*                                                                             *
+*  Description : Conserve une valeur en tant qu'expression de conversion.     *
+*                                                                             *
+*  Retour      : Nouvelle expression mise en place.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+arg_expr_t *build_arg_expr_from_number(unsigned long number)
+{
+    arg_expr_t *result;                     /* Structure à retourner       */
+
+    result = (arg_expr_t *)calloc(1, sizeof(arg_expr_t));
+
+    result->type = CET_NUMBER;
+
+    result->number = number;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : binval = valeur binaire à conserver dans sa forme brute.     *
+*                                                                             *
+*  Description : Conserve une valeur en tant qu'expression de conversion.     *
+*                                                                             *
+*  Retour      : Nouvelle expression mise en place.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+arg_expr_t *build_arg_expr_from_binval(char *binval)
+{
+    arg_expr_t *result;                     /* Structure à retourner       */
+
+    result = (arg_expr_t *)calloc(1, sizeof(arg_expr_t));
+
+    result->type = CET_BINVAL;
+
+    result->binval = binval;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : number = valeur hexadécimale à conserver dans sa forme brute.*
+*                                                                             *
+*  Description : Conserve une valeur en tant qu'expression de conversion.     *
+*                                                                             *
+*  Retour      : Nouvelle expression mise en place.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+arg_expr_t *build_arg_expr_from_hexval(char *hexval)
+{
+    arg_expr_t *result;                     /* Structure à retourner       */
+
+    result = (arg_expr_t *)calloc(1, sizeof(arg_expr_t));
+
+    result->type = CET_HEXVAL;
+
+    result->hexval = hexval;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item1 = premier élément à agréger.                           *
+*                item2 = second élément à agréger.                            *
+*                                                                             *
+*  Description : Construit une base d'expression de conversion composée.      *
+*                                                                             *
+*  Retour      : Nouvelle expression mise en place.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+arg_expr_t *build_composed_arg_expr(char *item1, char *item2)
+{
+    arg_expr_t *result;                     /* Structure à retourner       */
+
+    result = (arg_expr_t *)calloc(1, sizeof(arg_expr_t));
+
+    result->type = CET_COMPOSED;
+
+    result->comp_items = (char **)calloc(2, sizeof(char *));
+    result->comp_count = 2;
+
+    result->comp_items[0] = make_string_lower(item1);
+    result->comp_items[1] = make_string_lower(item2);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = expression déjà en place à compléter.                 *
+*                item = nouvel élément à agréger.                             *
+*                                                                             *
+*  Description : Etend une base d'expression de conversion composée.          *
+*                                                                             *
+*  Retour      : Expression en place et mise à jour.                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+arg_expr_t *extend_composed_arg_expr(arg_expr_t *expr, char *item)
+{
+    assert(expr->type == CET_COMPOSED);
+
+    expr->comp_items = (char **)realloc(expr->comp_items, ++expr->comp_count * sizeof(char *));
+
+    expr->comp_items[expr->comp_count - 1] = make_string_lower(item);
+
+    return expr;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = expression à encapsuler.                              *
+*                op   = opération unaire à associer à l'opération.            *
+*                                                                             *
+*  Description : Traduit une opération unaire sur expression de conversion.   *
+*                                                                             *
+*  Retour      : Nouvelle expression mise en place.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+arg_expr_t *build_unary_arg_expr(arg_expr_t *expr, ConvUnaryOperation op)
+{
+    arg_expr_t *result;                     /* Structure à retourner       */
+
+    result = (arg_expr_t *)calloc(1, sizeof(arg_expr_t));
+
+    result->type = CET_UNARY;
+
+    result->un_expr = expr;
+    result->un_op = op;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr1 = première expression à encapsuler.                    *
+*                expr2 = seconde expression à encapsuler.                     *
+*                op    = opération binaire à associer à l'opération.          *
+*                                                                             *
+*  Description : Traduit une opération binaire sur expression de conversion.  *
+*                                                                             *
+*  Retour      : Nouvelle expression mise en place.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+arg_expr_t *build_binary_arg_expr(arg_expr_t *expr1, arg_expr_t *expr2, ConvBinaryOperation op)
+{
+    arg_expr_t *result;                    /* Structure à retourner       */
+
+    result = (arg_expr_t *)calloc(1, sizeof(arg_expr_t));
+
+    result->type = CET_BINARY;
+
+    result->bin_expr1 = expr1;
+    result->bin_expr2 = expr2;
+    result->bin_op = op;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = expression à libérer de la mémoire.                   *
+*                                                                             *
+*  Description : Supprime tous les éléments mis en place pour un argument.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void delete_arg_expr(arg_expr_t *expr)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    switch (expr->type)
+    {
+        case CET_NAME:
+            free(expr->original);
+            free(expr->name);
+            break;
+
+        case CET_BINVAL:
+            free(expr->binval);
+            break;
+
+        case CET_HEXVAL:
+            free(expr->hexval);
+            break;
+
+        case CET_COMPOSED:
+            for (i = 0; i < expr->comp_count; i++)
+                free(expr->comp_items[i]);
+            free(expr->comp_items);
+            break;
+
+        case CET_UNARY:
+            delete_arg_expr(expr->un_expr);
+            break;
+
+        case CET_BINARY:
+            delete_arg_expr(expr->bin_expr1);
+            delete_arg_expr(expr->bin_expr2);
+            break;
+
+        default:
+            break;
+
+    }
+
+    free(expr);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = première expression à consulter.                      *
+*                bits = gestionnaire des bits d'encodage.                     *
+*                list = liste de l'ensemble des fonctions de conversion.      *
+*                size = taille déterminée avec précision. [OUT]               *
+*                                                                             *
+*  Description : Détermine la taille en bits d'une expression donnée.         *
+*                                                                             *
+*  Retour      : true si la taille a pu être déterminée, false sinon.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool compute_arg_expr_size(const arg_expr_t *expr, const coding_bits *bits, const conv_list *list, unsigned int *size)
+{
+    bool result;                            /* Bilan à retourner           */
+    raw_bitfield *field;                    /* Eventuel champ brut associé */
+    conv_func *func;                        /* Eventuelle fonction liée    */
+    size_t i;                               /* Boucle de parcours          */
+    unsigned int tmp;                       /* Stockage temporaire         */
+
+    switch (expr->type)
+    {
+        case CET_NAME:
+
+            result = find_var_by_name(bits, list, expr->name, &field, &func);
+
+            if (result)
+            {
+                if (field != NULL)
+                    *size = get_raw_bitfield_length(field);
+                else
+                    result = compute_conv_func_size(func, bits, list, size);
+            }
+
+            /**
+             * On autorise le passage de constante inconnue par d2c mais valable pour gcc.
+             */
+            else result = true;
+
+            break;
+
+        case CET_COMPOSED:
+
+            result = true;
+            *size = 0;
+
+            for (i = 0; i < expr->comp_count && result; i++)
+            {
+                if (isdigit(expr->comp_items[i][0]))
+                    *size += strlen(expr->comp_items[i]);
+
+                else
+                {
+                    if (!find_var_by_name(bits, list, expr->comp_items[i], &field, &func))
+                        result = false;
+
+                    else
+                    {
+                        if (field != NULL)
+                            *size += get_raw_bitfield_length(field);
+                        else
+                        {
+                            result = compute_conv_func_size(func, bits, list, &tmp);
+                            *size += tmp;
+                        }
+                    }
+
+                }
+
+            }
+
+            break;
+
+        case CET_UNARY:
+            result = compute_arg_expr_size(expr->un_expr, bits, list, size);
+            break;
+
+        case CET_BINARY:
+
+            result = compute_arg_expr_size(expr->bin_expr1, bits, list, &tmp);
+
+            if (result)
+                result = compute_arg_expr_size(expr->bin_expr1, bits, list, size);
+
+            if (tmp > *size) *size = tmp;
+
+            break;
+
+        default:
+            result = false;
+            break;
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = première expression à encapsuler.                     *
+*                fd   = descripteur d'un flux ouvert en écriture.             *
+*                bits = gestionnaire des bits d'encodage.                     *
+*                list = liste de l'ensemble des fonctions de conversion.      *
+*                data = éventuelle donnée à transmettre à chaque visite.      *
+*                                                                             *
+*  Description : Visite une expression en traitant en premier ses composantes.*
+*                                                                             *
+*  Retour      : Bilan des traitements effectués.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool visit_arg_expr(arg_expr_t *expr, visit_expr_fc visit, int fd, const coding_bits *bits, const conv_list *list, void *data)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    switch (expr->type)
+    {
+        case CET_UNARY:
+            result = visit_arg_expr(expr->un_expr, visit, fd, bits, list, data);
+            break;
+
+        case CET_BINARY:
+            result = visit_arg_expr(expr->bin_expr1, visit, fd, bits, list, data);
+            result = visit_arg_expr(expr->bin_expr2, visit, fd, bits, list, data);
+            break;
+
+        default:
+            result = true;
+            break;
+
+    }
+
+    result &= visit(expr, fd, bits, list, data);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bits  = gestionnaire des bits d'encodage.                    *
+*                list  = liste de l'ensemble des fonctions de conversion.     *
+*                name  = déssignation de la variable recherchée.              *
+*                field = éventuel élement brut de décodage.                   *
+*                func  = éventuelle fonction de conversion pour intermédiaire.*
+*                                                                             *
+*  Description : Retrouve si elle existe une variable manipulée.              *
+*                                                                             *
+*  Retour      : Bilan des recherches : trouvaille ou non ?                   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool find_var_by_name(const coding_bits *bits, const conv_list *list, const char *name, raw_bitfield **field, conv_func **func)
+{
+    bool result;                            /* Bilan à retourner           */
+    raw_bitfield *cached_field;             /* Champ, version cachée       */
+    conv_func *cached_func;                 /* Fonction, version cachée    */
+
+    cached_field = find_named_field_in_bits(bits, name);
+    result = (cached_field != NULL);
+
+    if (!result)
+    {
+        cached_func = find_named_conv_in_list(list, name);
+        result = (cached_func != NULL);
+    }
+    else
+        cached_func = NULL;
+
+    if (field != NULL) *field = cached_field;
+    if (func != NULL) *func = cached_func;
+
+    if (!result)
+        fprintf(stderr, "Variable '%s' not found!\n", name);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = première expression à encapsuler.                     *
+*                bits = gestionnaire des bits d'encodage.                     *
+*                list = liste de l'ensemble des fonctions de conversion.      *
+*                                                                             *
+*  Description : S'assure du marquage des expressions pre-requises.           *
+*                                                                             *
+*  Retour      : Bilan des traitements effectués.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_arg_expr_content_fully_marked(arg_expr_t *expr, const coding_bits *bits, const conv_list *list)
+{
+    bool mark_sub_expr(arg_expr_t *sub, int dummy, const coding_bits *bts, const conv_list *lst, void *unused)
+    {
+        bool result;                        /* Bilan à retourner           */
+        size_t i;                           /* Boucle de parcours          */
+
+        bool mark_by_name(const coding_bits *_bts, const conv_list *_lst, const char *name)
+        {
+            bool found;                     /* Bilan d'opération à renvoyer*/
+            raw_bitfield *field;            /* Eventuel champ brut associé */
+            conv_func *func;                /* Eventuelle fonction liée    */
+
+            found = find_var_by_name(bts, lst, name, &field, &func);
+
+            if (found)
+            {
+                if (field != NULL)
+                    mark_raw_bitfield_as_used(field);
+                else /*if (func != NULL) */
+                    mark_conv_func(func, bts, lst);
+
+                printf(" VAR '%s' found (bf=%d  fc=%d)\n", name, !!field, !!func);
+
+
+            }
+            else printf(" VAR '%s' not found...\n", name);
+
+            return found;
+
+        }
+
+        /* Il est uniquement nécessaire de s'attacher aux références */
+        switch (sub->type)
+        {
+            case CET_NAME:
+                /* result = */mark_by_name(bits, lst, sub->name);
+                result = true;
+                break;
+
+            case CET_COMPOSED:
+                result = true;
+                for (i = 0; i < sub->comp_count && result; i++)
+                    if (!isdigit(sub->comp_items[i][0]))
+                        result = mark_by_name(bits, lst, sub->comp_items[i]);
+                break;
+
+            default:
+                result = true;
+                break;
+
+        }
+
+        return result;
+
+    }
+
+    return visit_arg_expr(expr, (visit_expr_fc)mark_sub_expr, -1, bits, list, NULL);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = première expression à encapsuler.                     *
+*                fd   = descripteur d'un flux ouvert en écriture.             *
+*                arch = architecture visée par l'opération globale.           *
+*                bits = gestionnaire des bits d'encodage.                     *
+*                list = liste de l'ensemble des fonctions de conversion.      *
+*                wide = taille des mots décodés.                              *
+*                                                                             *
+*  Description : S'assure de la déclaration des expressions pre-requises.     *
+*                                                                             *
+*  Retour      : Bilan des traitements effectués.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_arg_expr_content_fully_declared(arg_expr_t *expr, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide)
+{
+    bool declare_sub_expr(arg_expr_t *sub, int f, const coding_bits *bts, const conv_list *lst, unsigned int *wide)
+    {
+        bool result;                        /* Bilan à retourner           */
+        size_t i;                           /* Boucle de parcours          */
+
+        /* Si l'expression a déjà été définie lors d'un précédent besoin... */
+        printf("  sub declared ? %d  --  type = %d\n", sub->declared, sub->type);
+        if (sub->declared) return true;
+
+        bool declare_by_name(int _f, const coding_bits *_bts, const conv_list *_lst, unsigned int _wide, const char *name)
+        {
+            bool found;                     /* Bilan d'opération à renvoyer*/
+            conv_func *func;                /* Eventuelle fonction liée    */
+
+            found = find_var_by_name(bts, lst, name, NULL, &func);
+
+            if (found && func != NULL)
+            {
+                printf("========= DECLARE for '%s'\n", name);
+                found = declare_conv_func(func, _f, _bts, _lst, _wide);
+                printf("========= END DECLARE for '%s'\n", name);
+
+                /**
+                 * Si on déclare les variables suivantes dans declare_conv_func(),
+                 * elles seront également déclarées pour les fonctions de conversion
+                 * racine à partir de declare_syntax_items(), ce qui ne convient pas
+                 * car les appels racine servent directement d'arguments.
+                 */
+
+                if (is_conv_func_expression(func))
+                    dprintf(_f, "\t\tuint%u_t val_%s; // Ho\n", _wide, name);
+                else
+                    dprintf(_f, "\t\tGArchOperand *val_%s;;;;;\n", name);
+
+            }
+
+            return found;
+
+        }
+
+        /* Il est uniquement nécessaire de s'attacher aux références */
+        switch (sub->type)
+        {
+            case CET_NAME:
+                /* result = */declare_by_name(f, bits, lst, *wide, sub->name);
+                result = true;
+                break;
+
+            case CET_COMPOSED:
+                result = true;
+                for (i = 0; i < sub->comp_count && result; i++)
+                    if (!isdigit(sub->comp_items[i][0]))
+                        printf("... trying to declare... '%s'\n", sub->comp_items[i]);
+                for (i = 0; i < sub->comp_count && result; i++)
+                    if (!isdigit(sub->comp_items[i][0]))
+                        result = declare_by_name(f, bits, lst, *wide, sub->comp_items[i]);
+                break;
+
+            default:
+                result = true;
+                break;
+
+        }
+
+        sub->declared = result;
+
+        return result;
+
+    }
+
+    return visit_arg_expr(expr, (visit_expr_fc)declare_sub_expr, fd, bits, list, &wide);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = première expression à encapsuler.                     *
+*                fd   = descripteur d'un flux ouvert en écriture.             *
+*                arch = architecture visée par l'opération globale.           *
+*                bits = gestionnaire des bits d'encodage.                     *
+*                list = liste de l'ensemble des fonctions de conversion.      *
+*                pp   = pré-processeur pour les échanges de chaînes.          *
+*                                                                             *
+*  Description : S'assure de la définition des expressions pre-requises.      *
+*                                                                             *
+*  Retour      : Bilan des traitements effectués.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_arg_expr_content_fully_defined(arg_expr_t *expr, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp)
+{
+    typedef struct _def_info
+    {
+        const char *arch;
+        const pre_processor *pp;
+
+    } def_info;
+
+    def_info info;                          /* Transmissions au visiteur   */
+
+    bool define_sub_expr(arg_expr_t *sub, int f, const coding_bits *bts, const conv_list *lst, def_info *info)
+    {
+        bool result;                        /* Bilan à retourner           */
+        size_t i;                           /* Boucle de parcours          */
+
+        /* Si l'expression a déjà été définie lors d'un précédent besoin... */
+        if (sub->defined) return true;
+
+        bool define_by_name(int _f, const coding_bits *_bts, const conv_list *_lst, def_info *_info, const char *name)
+        {
+            bool found;                     /* Bilan d'opération à renvoyer*/
+            conv_func *func;                /* Eventuelle fonction liée    */
+
+            found = find_var_by_name(bts, lst, name, NULL, &func);
+
+            if (found && func != NULL)
+                found = define_conv_func(func, false, false, _f, _info->arch, _bts, _lst, _info->pp);
+
+            return found;
+
+        }
+
+        /* Il est uniquement nécessaire de s'attacher aux références */
+        switch (sub->type)
+        {
+            case CET_NAME:
+                /* result = */define_by_name(f, bits, lst, info, sub->name);
+                result = true;
+                break;
+
+            case CET_COMPOSED:
+                result = true;
+                for (i = 0; i < sub->comp_count && result; i++)
+                    if (!isdigit(sub->comp_items[i][0]))
+                        result = define_by_name(f, bits, lst, info, sub->comp_items[i]);
+                break;
+
+            default:
+                result = true;
+                break;
+
+        }
+
+        sub->defined = result;
+
+        return result;
+
+    }
+
+    info.arch = arch;
+    info.pp = pp;
+
+    return visit_arg_expr(expr, (visit_expr_fc)define_sub_expr, fd, bits, list, &info);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = première expression à encapsuler.                     *
+*                fd   = descripteur d'un flux ouvert en écriture.             *
+*                bits = gestionnaire des bits d'encodage.                     *
+*                list = liste de l'ensemble des fonctions de conversion.      *
+*                                                                             *
+*  Description : Définit une expression utilisée dans une conversion.         *
+*                                                                             *
+*  Retour      : Bilan des traitements effectués.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool define_arg_expr(const arg_expr_t *expr, int fd, const coding_bits *bits, const conv_list *list)
+{
+    bool result;                            /* Bilan à retourner           */
+    raw_bitfield *field;                    /* Eventuel champ brut associé */
+    conv_func *func;                        /* Eventuelle fonction liée    */
+    unsigned int max_size;                  /* Quantité de bits totale     */
+    size_t i;                               /* Boucle de parcours          */
+    const char *cname;                      /* Raccourci de confort        */
+    unsigned int used_size;                 /* Quantité de bits utilisée   */
+
+    result = true;
+
+    switch (expr->type)
+    {
+        case CET_NAME:
+
+            if (!find_var_by_name(bits, list, expr->name, &field, &func))
+                dprintf(fd, "%s", expr->original);
+
+            else
+            {
+                if (field != NULL)
+                    dprintf(fd, "raw_%s", expr->name);
+                else
+                    dprintf(fd, "val_%s", expr->name);
+            }
+
+            break;
+
+        case CET_NUMBER:
+            dprintf(fd, "%lu", expr->number);
+            break;
+
+        case CET_BINVAL:
+            dprintf(fd, "b%s", expr->binval);
+            break;
+
+        case CET_HEXVAL:
+            dprintf(fd, "0x%s", expr->hexval);
+            break;
+
+        case CET_COMPOSED:
+
+            result = compute_arg_expr_size(expr, bits, list, &max_size);
+
+            printf("MAX SIZE :: %u\n", max_size);
+
+            for (i = 0; i < expr->comp_count && result; i++)
+            {
+                cname = expr->comp_items[i];
+
+                if (i > 0)
+                    dprintf(fd, " | ");
+
+                /* Constante binaire ? */
+                if (isdigit(cname[0]))
+                {
+                    max_size -= strlen(cname);
+
+                    if (max_size == 0)
+                        dprintf(fd, "b%s", cname);
+                    else
+                        dprintf(fd, "b%s << %u", cname, max_size);
+
+                }
+
+                /* Ou variable définie ? */
+                else
+                {
+                    result = find_var_by_name(bits, list, cname, &field, &func);
+
+                    if (result)
+                    {
+                        if (field != NULL)
+                            used_size = get_raw_bitfield_length(field);
+                        else
+                            /*result = */compute_conv_func_size(func, bits, list, &used_size);
+
+                        max_size -= used_size;
+
+                        if (field != NULL)
+                        {
+                            if (max_size == 0)
+                                dprintf(fd, "raw_%s", cname);
+                            else
+                                dprintf(fd, "raw_%s << %u", cname, max_size);
+                        }
+                        else
+                        {
+                            if (max_size == 0)
+                                dprintf(fd, "val_%s", cname);
+                            else
+                                dprintf(fd, "val_%s << %u", cname, max_size);
+                        }
+
+                    }
+
+                }
+
+            }
+
+            break;
+
+        case CET_UNARY:
+
+            switch (expr->un_op)
+            {
+                case CUO_NOT:
+                    dprintf(fd, "!");
+                    break;
+                default:
+                    result = false;
+                    break;
+            }
+
+            result &= define_arg_expr(expr->un_expr, fd, bits, list);
+
+            break;
+
+        case CET_BINARY:
+
+            dprintf(fd, "(");
+
+            result = define_arg_expr(expr->bin_expr1, fd, bits, list);
+
+            switch (expr->bin_op)
+            {
+                case CBO_AND:
+                    dprintf(fd, " & ");
+                    break;
+                case CBO_EOR:
+                    dprintf(fd, " ^ ");
+                    break;
+                default:
+                    result = false;
+                    break;
+            }
+
+            result &= define_arg_expr(expr->bin_expr2, fd, bits, list);
+
+            dprintf(fd, ")");
+
+            break;
+
+        default:
+            result = false;
+            break;
+
+    }
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                         MANIPULATION DE LISTES D'ARGUMENTS                         */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = expression initial pour constituer une liste.         *
+*                                                                             *
+*  Description : Crée une liste d'arguments de conversion.                    *
+*                                                                             *
+*  Retour      : Nouvelle structure mise en place.                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+arg_list_t *build_arg_list(arg_expr_t *expr)
+{
+    arg_list_t *result;                     /* Structure à retourner       */
+
+    result = (arg_list_t *)calloc(1, sizeof(arg_list_t));
+
+    result->items = (arg_expr_t **)calloc(1, sizeof(arg_expr_t *));
+    result->count = 1;
+
+    result->items[0] = expr;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list = liste d'expressions à supprimer de la mémoire.        *
+*                                                                             *
+*  Description : Libère la mémoire occupée par une liste d'expressions.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void delete_arg_list(arg_list_t *list)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < list->count; i++)
+        delete_arg_expr(list->items[i]);
+
+    if (list->items != NULL)
+        free(list->items);
+
+    free(list);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list = liste d'expressions à supprimer de la mémoire. [OUT]  *
+*                expr = expression à ajouter à la liste courante.             *
+*                                                                             *
+*  Description : Ajoute un élément à une liste d'arguments de conversion.     *
+*                                                                             *
+*  Retour      : Structure en place mise à jour.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+arg_list_t *extend_arg_list(arg_list_t *list, arg_expr_t *expr)
+{
+    list->items = (arg_expr_t **)realloc(list->items, ++list->count * sizeof(arg_expr_t *));
+
+    list->items[list->count - 1] = expr;
+
+    return list;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : args = liste d'expressions à supprimer de la mémoire.        *
+*                bits = gestionnaire des bits d'encodage.                     *
+*                list = liste de l'ensemble des fonctions de conversion.      *
+*                                                                             *
+*  Description : S'assure du marquage des expressions pre-requises.           *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_arg_list_content_fully_marked(arg_list_t *args, const coding_bits *bits, const conv_list *list)
+{
+    bool result;                            /* Bilan à remonter            */
+    size_t i;                               /* Boucle de parcours          */
+
+    result = true;
+
+    for (i = 0; i < args->count && result; i++)
+        result = ensure_arg_expr_content_fully_marked(args->items[i], bits, list);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : args = liste d'expressions à supprimer de la mémoire.        *
+*                fd   = descripteur d'un flux ouvert en écriture.             *
+*                bits = gestionnaire des bits d'encodage.                     *
+*                list = liste de l'ensemble des fonctions de conversion.      *
+*                wide = taille des mots décodés.                              *
+*                                                                             *
+*  Description : S'assure de la déclaration des expressions pre-requises.     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_arg_list_content_fully_declared(arg_list_t *args, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide)
+{
+    bool result;                            /* Bilan à remonter            */
+    size_t i;                               /* Boucle de parcours          */
+
+    result = true;
+
+    for (i = 0; i < args->count && result; i++)
+        result = ensure_arg_expr_content_fully_declared(args->items[i], fd, bits, list, wide);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : args = liste d'expressions à supprimer de la mémoire.        *
+*                fd   = descripteur d'un flux ouvert en écriture.             *
+*                arch = architecture visée par l'opération globale.           *
+*                bits = gestionnaire des bits d'encodage.                     *
+*                list = liste de l'ensemble des fonctions de conversion.      *
+*                pp   = pré-processeur pour les échanges de chaînes.          *
+*                                                                             *
+*  Description : S'assure de la définition des expressions pre-requises.      *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_arg_list_content_fully_defined(arg_list_t *args, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp)
+{
+    bool result;                            /* Bilan à remonter            */
+    size_t i;                               /* Boucle de parcours          */
+
+    result = true;
+
+    for (i = 0; i < args->count && result; i++)
+        result = ensure_arg_expr_content_fully_defined(args->items[i], fd, arch, bits, list, pp);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : args = liste d'expressions à supprimer de la mémoire.        *
+*                fd   = descripteur d'un flux ouvert en écriture.             *
+*                bits = gestionnaire des bits d'encodage.                     *
+*                list = liste de l'ensemble des fonctions de conversion.      *
+*                                                                             *
+*  Description : Définit les variables associées à un appel de fonction.      *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool define_arg_list(const arg_list_t *args, int fd, const coding_bits *bits, const conv_list *list)
+{
+    bool result;                            /* Bilan à remonter            */
+    size_t i;                               /* Boucle de parcours          */
+
+    result = true;
+
+    for (i = 0; i < args->count && result; i++)
+    {
+        if (i > 0) dprintf(fd, ", ");
+        result = define_arg_expr(args->items[i], fd, bits, list);
+    }
+
+    return result;
+
+}
diff --git a/tools/d2c/args/manager.h b/tools/d2c/args/manager.h
new file mode 100644
index 0000000..85fc0a8
--- /dev/null
+++ b/tools/d2c/args/manager.h
@@ -0,0 +1,138 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * manager.h - prototypes pour la gestion des arguments dans leur ensemble
+ *
+ * Copyright (C) 2015 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _TOOLS_D2C_ARGS_MANAGER_H
+#define _TOOLS_D2C_ARGS_MANAGER_H
+
+
+#include "../pproc.h"
+#include "../bits/manager.h"
+
+
+/* Liste des fonctions de conversions présentes */
+typedef struct _conv_list conv_list;
+
+
+
+/* -------------------------- REPRESENTATION D'UN ARGUMENT -------------------------- */
+
+
+/* Types d'opérations unaires */
+typedef enum _ConvUnaryOperation
+{
+    CUO_NOT,                                /* NOT (booléen)               */
+
+    CUO_COUNT
+
+} ConvUnaryOperation;
+
+/* Types d'opérations binaires */
+typedef enum _ConvBinaryOperation
+{
+    CBO_AND,                                /* Et logique                  */
+    CBO_EOR,                                /* Ou exclusif (booléen)       */
+
+    CBO_COUNT
+
+} ConvBinaryOperation;
+
+
+/* Représentation d'une expression de conversion */
+typedef struct _arg_expr_t arg_expr_t;
+
+
+/* Référence une variable en tant qu'expression de conversion. */
+arg_expr_t *build_arg_expr_from_name(char *);
+
+/* Conserve une valeur en tant qu'expression de conversion. */
+arg_expr_t *build_arg_expr_from_number(unsigned long );
+
+/* Conserve une valeur en tant qu'expression de conversion. */
+arg_expr_t *build_arg_expr_from_binval(char *);
+
+/* Conserve une valeur en tant qu'expression de conversion. */
+arg_expr_t *build_arg_expr_from_hexval(char *);
+
+/* Construit une base d'expression de conversion composée. */
+arg_expr_t *build_composed_arg_expr(char *, char *);
+
+/* Etend une base d'expression de conversion composée. */
+arg_expr_t *extend_composed_arg_expr(arg_expr_t *, char *);
+
+/* Traduit une opération unaire sur expression de conversion. */
+arg_expr_t *build_unary_arg_expr(arg_expr_t *, ConvUnaryOperation);
+
+/* Traduit une opération binaire sur expression de conversion. */
+arg_expr_t *build_binary_arg_expr(arg_expr_t *, arg_expr_t *, ConvBinaryOperation);
+
+/* Supprime tous les éléments mis en place pour un argument. */
+void delete_arg_expr(arg_expr_t *);
+
+/* Détermine la taille en bits d'une expression donnée. */
+bool compute_arg_expr_size(const arg_expr_t *, const coding_bits *, const conv_list *, unsigned int *);
+
+/* S'assure du marquage des expressions pre-requises. */
+bool ensure_arg_expr_content_fully_marked(arg_expr_t *, const coding_bits *, const conv_list *);
+
+/* S'assure de la déclaration des expressions pre-requises. */
+bool ensure_arg_expr_content_fully_declared(arg_expr_t *, int, const coding_bits *, const conv_list *, unsigned int);
+
+/* S'assure de la définition des expressions pre-requises. */
+bool ensure_arg_expr_content_fully_defined(arg_expr_t *, int, const char *, const coding_bits *, const conv_list *, const pre_processor *);
+
+/* Définit une expression utilisée dans une conversion. */
+bool define_arg_expr(const arg_expr_t *, int, const coding_bits *, const conv_list *);
+
+
+
+/* ----------------------- MANIPULATION DE LISTES D'ARGUMENTS ----------------------- */
+
+
+/* Liste d'expressions utilisées en arguments de conversion */
+typedef struct _arg_list_t arg_list_t;
+
+
+/* Crée une liste d'arguments de conversion. */
+arg_list_t *build_arg_list(arg_expr_t *);
+
+/* Libère la mémoire occupée par une liste d'expressions. */
+void delete_arg_list(arg_list_t *);
+
+/* Ajoute un élément à une liste d'arguments de conversion. */
+arg_list_t *extend_arg_list(arg_list_t *, arg_expr_t *);
+
+/* S'assure du marquage des expressions pre-requises. */
+bool ensure_arg_list_content_fully_marked(arg_list_t *, const coding_bits *, const conv_list *);
+
+/* S'assure de la déclaration des expressions pre-requises. */
+bool ensure_arg_list_content_fully_declared(arg_list_t *, int, const coding_bits *, const conv_list *, unsigned int);
+
+/* S'assure de la définition des expressions pre-requises. */
+bool ensure_arg_list_content_fully_defined(arg_list_t *, int, const char *, const coding_bits *, const conv_list *, const pre_processor *);
+
+/* Définit les variables associées à un appel de fonction. */
+bool define_arg_list(const arg_list_t *, int, const coding_bits *, const conv_list *);
+
+
+
+#endif  /* _TOOLS_D2C_ARGS_MANAGER_H */
diff --git a/tools/d2c/args/tokens.l b/tools/d2c/args/tokens.l
new file mode 100644
index 0000000..4b1a2a1
--- /dev/null
+++ b/tools/d2c/args/tokens.l
@@ -0,0 +1,67 @@
+
+%top {
+
+#include "grammar.h"
+
+}
+
+
+%option noyywrap
+%option nounput
+%option noinput
+%option yylineno
+%option stack
+%option noyy_top_state
+
+%x binval
+%x hexval
+
+
+%%
+
+
+%{
+
+    /* Choix d'un des démarrages multiples */
+    if (*init_token != ALLOW_ALL)
+    {
+        unsigned int first;
+        first = *init_token;
+        *init_token = ALLOW_ALL;
+        return first;
+    }
+
+%}
+
+
+[A-Za-z_][A-Za-z0-9_]*      {
+                                if (strcmp(yytext, "NOT") == 0) return NOT;
+                                else if (strcmp(yytext, "AND") == 0) return AND_LOG;
+                                else if (strcmp(yytext, "EOR") == 0) return EOR;
+                                else
+                                {
+                                    yylvalp->string = strdup(yytext);
+                                    return NAME;
+                                }
+                            }
+
+[0-9][0-9]*                 { yylvalp->integer = atoi(yytext); return NUMBER; }
+
+"'"                         { yy_push_state(binval); }
+<binval>[01][01]*           { yylvalp->string = strdup(yytext); return BINVAL; }
+<binval>"'"                 { yy_pop_state(); }
+
+"0x"                        { yy_push_state(hexval); }
+<hexval>[0-9a-f][0-9a-f]*   { yylvalp->string = strdup(yytext); yy_pop_state(); return HEXVAL; }
+
+","                         { return COMMA; }
+":"                         { return COLON; }
+"&"                         { return AND_LOG; }
+
+"("                         { yy_push_state(INITIAL); return OP; }
+")"                         { yy_pop_state(); return CP; }
+
+[ ]+                        { }
+
+
+%%
diff --git a/tools/d2c/bits.c b/tools/d2c/bits.c
deleted file mode 100644
index 4169acf..0000000
--- a/tools/d2c/bits.c
+++ /dev/null
@@ -1,385 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * bits.c - compréhension et manipulation des champs de bits
- *
- * Copyright (C) 2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  OpenIDA is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  OpenIDA is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "bits.h"
-
-
-#include <assert.h>
-#include <inttypes.h>
-#include <malloc.h>
-#include <stdint.h>
-#include <string.h>
-
-
-#include "helpers.h"
-
-
-
-
-
-/* --------------------------- GESTION DES CHAMPS DE BITS --------------------------- */
-
-
-/* Elément d'un mot décodé */
-struct _raw_bitfield
-{
-    char *name;                             /* Désignation humaine         */
-    unsigned int start;                     /* Position de départ          */
-    unsigned int length;                    /* Taille du champ             */
-
-    bool used;                              /* Champ défini & utilisé      */
-
-};
-
-
-
-
-/* Représentation de l'ensemble des bits de codage */
-struct _coding_bits
-{
-    raw_bitfield *fields;                   /* Champs de bits détectés     */
-    size_t bf_count;                        /* Nombre de ces champs        */
-    uint64_t bits;                          /* Bits invariables            */
-    uint64_t mask;                          /* Emplacement de ces bits     */
-    unsigned int curpos;                    /* Position pendant l'analyse  */
-
-};
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : field = champ de bits à consulter.                           *
-*                                                                             *
-*  Description : Indique le nombre de bits utilisés par le champ.             *
-*                                                                             *
-*  Retour      : Nombre de bits considérés.                                   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-unsigned int get_raw_bitfield_length(const raw_bitfield *field)
-{
-    return field->length;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : field = champ de bits à traiter.                             *
-*                                                                             *
-*  Description : Marque un champ de bits comme étant utile.                   *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void mark_raw_bitfield_as_used(raw_bitfield *field)
-{
-    field->used = true;
-
-}
-
-
-
-
-
-
-
-
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : -                                                            *
-*                                                                             *
-*  Description : Crée un nouveau gestionnaire des bits d'encodage brut.       *
-*                                                                             *
-*  Retour      : Nouvelle structure prête à emploi.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-coding_bits *create_coding_bits(void)
-{
-    coding_bits *result;                    /* Définition vierge à renvoyer*/
-
-    result = (coding_bits *)calloc(1, sizeof(coding_bits));
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : bits = gestionnaire d'un ensemble de bits à libérer.         *
-*                                                                             *
-*  Description : Supprime de la mémoire un gestionnaire de bits d'encodage.   *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void delete_coding_bits(coding_bits *bits)
-{
-    size_t i;                               /* Boucle de parcours          */
-
-    for (i = 0; i < bits->bf_count; i++)
-        free(bits->fields[i].name);
-
-    if (bits->fields != NULL)
-        free(bits->fields);
-
-    free(bits);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : bits   = gestionnaire de bits d'encodage brut à consulter.   *
-*                name   = désignation humaine du champ remarqué.              *
-*                length = taille du champ à mémoriser.                        *
-*                                                                             *
-*  Description : Note la présence d'un champ remarquable dans une définition. *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void register_named_field_in_bits(coding_bits *bits, char *name, unsigned int length)
-{
-    raw_bitfield *field;                    /* Nouveau champ à constituer  */
-
-    assert((bits->curpos + length) < 64);
-
-    bits->fields = (raw_bitfield *)realloc(bits->fields,
-                                              ++bits->bf_count * sizeof(raw_bitfield));
-
-    field = &bits->fields[bits->bf_count - 1];
-
-    field->name = make_string_lower(name);
-    field->start = bits->curpos;
-    field->length = length;
-
-    bits->curpos += length;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : bits = gestionnaire de bits d'encodage brut à consulter.     *
-*                val  = valeur du bit à prendre en compte.                    *
-*                                                                             *
-*  Description : Note la présence d'un bit invariable dans une définition.    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void register_bit_in_bits(coding_bits *bits, int val)
-{
-    assert(bits->curpos < 64);
-
-    bits->bits |= (val ? 1 : 0) << bits->curpos;
-    bits->mask |= 1 << bits->curpos;
-
-    bits->curpos++;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : bits = gestionnaire de bits d'encodage brut à consulter.     *
-*                                                                             *
-*  Description : Indique le nombre de bits traités.                           *
-*                                                                             *
-*  Retour      : Quantité, positive ou nulle.                                 *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-unsigned int count_coded_bits(const coding_bits *bits)
-{
-    return bits->curpos;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : bits = gestionnaire d'encodage brut à consulter.             *
-*                name = désignation humaine du champ à retrouver.             *
-*                                                                             *
-*  Description : Recherche un champ donné dans un ensemble de champs de bits. *
-*                                                                             *
-*  Retour      : Structure associée au champ trouvé ou NULL en cas d'échec.   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-raw_bitfield *find_named_field_in_bits(const coding_bits *bits, const char *name)
-{
-    raw_bitfield *result;                   /* Champ de bits à retourner   */
-    size_t i;                               /* Boucle de parcours          */
-
-    result = NULL;
-
-    for (i = 0; i < bits->bf_count && result == NULL; i++)
-        if (strcmp(bits->fields[i].name, name) == 0)
-            result = &bits->fields[i];
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : spec    = spécification servant de base à l'opération.       *
-*                fd      = descripteur d'un flux ouvert en écriture.          *
-*                wide    = taille des mots manipulés (en bits).               *
-*                                                                             *
-*  Description : Déclare les variables C associées aux champs de bits.        *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool declare_used_bits_fields(const coding_bits *bits, int fd, unsigned int wide)
-{
-    size_t i;                               /* Boucle de parcours          */
-
-    for (i = 0; i < bits->bf_count; i++)
-        if (bits->fields[i].used)
-            dprintf(fd, "\t\tuint%u_t raw_%s;\n", wide, bits->fields[i].name);
-
-    return true;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : spec    = spécification servant de base à l'opération.       *
-*                fd      = descripteur d'un flux ouvert en écriture.          *
-*                                                                             *
-*  Description : Vérifie que les bits fixes correspondent au masque attendu.  *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool check_bits_correctness(const coding_bits *bits, int fd)
-{
-    switch (bits->curpos)
-    {
-        case 8:
-            dprintf(fd, "\t\tif ((raw & 0x%" PRIx8 ") != 0x%" PRIx8 ") return NULL;\n",
-                    (uint8_t)bits->mask, (uint8_t)bits->bits);
-            break;
-
-        case 16:
-            dprintf(fd, "\t\tif ((raw & 0x%" PRIx16 ") != 0x%" PRIx16 ") return NULL;\n",
-                    (uint16_t)bits->mask, (uint16_t)bits->bits);
-            break;
-
-        case 32:
-            dprintf(fd, "\t\tif ((raw & 0x%" PRIx32 ") != 0x%" PRIx32 ") return NULL;\n",
-                    (uint32_t)bits->mask, (uint32_t)bits->bits);
-            break;
-
-        case 64:
-            dprintf(fd, "\t\tif ((raw & 0x%" PRIx64 ") != 0x%" PRIx64 ") return NULL;\n",
-                    bits->mask, bits->bits);
-            break;
-
-    }
-
-    return true;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : spec    = spécification servant de base à l'opération.       *
-*                fd      = descripteur d'un flux ouvert en écriture.          *
-*                                                                             *
-*  Description : Définit les variables C associées aux champs de bits.        *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool define_used_bits_fields(const coding_bits *bits, int fd)
-{
-    size_t i;                               /* Boucle de parcours          */
-    raw_bitfield *rf;                       /* Accès confortable à un champ*/
-
-    for (i = 0; i < bits->bf_count; i++)
-    {
-        rf = &bits->fields[i];
-        if (!rf->used) continue;
-
-        dprintf(fd, "\t\traw_%s = (_raw >> %u) & 0x%llx;\n", rf->name, rf->start, (1ull << rf->length) - 1);
-
-    }
-
-    return true;
-
-}
diff --git a/tools/d2c/bits.h b/tools/d2c/bits.h
deleted file mode 100644
index aa4b7aa..0000000
--- a/tools/d2c/bits.h
+++ /dev/null
@@ -1,87 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * bits.h - prototypes pour la compréhension et la manipulation des champs de bits
- *
- * Copyright (C) 2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  OpenIDA is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  OpenIDA is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _TOOLS_BITS_H
-#define _TOOLS_BITS_H
-
-
-#include <stdbool.h>
-
-
-
-
-/* --------------------------- GESTION DES CHAMPS DE BITS --------------------------- */
-
-
-/* Elément d'un mot décodé */
-typedef struct _raw_bitfield raw_bitfield;
-
-
-
-/* Indique le nombre de bits utilisés par le champ. */
-unsigned int get_raw_bitfield_length(const raw_bitfield *);
-
-/* Marque un champ de bits comme étant utile. */
-void mark_raw_bitfield_as_used(raw_bitfield *);
-
-
-
-
-
-/* Représentation de l'ensemble des bits de codage */
-typedef struct _coding_bits coding_bits;
-
-
-
-/* Crée un nouveau gestionnaire des bits d'encodage brut. */
-coding_bits *create_coding_bits(void);
-
-/* Supprime de la mémoire un gestionnaire de bits d'encodage. */
-void delete_coding_bits(coding_bits *);
-
-
-
-/* Note la présence d'un champ remarquable dans une définition. */
-void register_named_field_in_bits(coding_bits *, char *, unsigned int);
-
-/* Note la présence d'un bit invariable dans une définition. */
-void register_bit_in_bits(coding_bits *, int);
-
-/* Indique le nombre de bits traités. */
-unsigned int count_coded_bits(const coding_bits *);
-
-/* Recherche un champ donné dans un ensemble de champs de bits. */
-raw_bitfield *find_named_field_in_bits(const coding_bits *, const char *);
-
-/* Déclare les variables C associées aux champs de bits. */
-bool declare_used_bits_fields(const coding_bits *, int, unsigned int);
-
-/* Vérifie que les bits fixes correspondent au masque attendu. */
-bool check_bits_correctness(const coding_bits *, int);
-
-/* Définit les variables C associées aux champs de bits. */
-bool define_used_bits_fields(const coding_bits *, int);
-
-
-
-#endif  /* _TOOLS_BITS_H */
diff --git a/tools/d2c/bits/Makefile.am b/tools/d2c/bits/Makefile.am
new file mode 100644
index 0000000..415e2a6
--- /dev/null
+++ b/tools/d2c/bits/Makefile.am
@@ -0,0 +1,31 @@
+
+BUILT_SOURCES = grammar.h
+
+
+# On évite d'utiliser les variables personnalisées de type *_la_[YL]FLAGS
+# afin de conserver des noms de fichiers simples, ie sans le nom de la
+# bibliothèque de sortie en préfixe.
+
+AM_YFLAGS = -v -d -p bits_
+
+AM_LFLAGS = -P bits_ -o lex.yy.c --header-file=tokens.h			\
+			-Dyylval=bits_lval -Dyyget_lineno=bits_get_lineno 	\
+			-Dyy_scan_string=bits__scan_string					\
+			-Dyy_delete_buffer=bits__delete_buffer
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS)
+
+
+noinst_LTLIBRARIES  = libd2cbits.la
+
+.NOTPARALLEL: $(noinst_LTLIBRARIES)
+
+libd2cbits_la_SOURCES =					\
+	decl.h								\
+	manager.h manager.c					\
+	tokens.l							\
+	grammar.y
+
+
+# Automake fait les choses à moitié
+CLEANFILES = grammar.h grammar.c grammar.output tokens.c tokens.h
diff --git a/tools/d2c/bits/decl.h b/tools/d2c/bits/decl.h
new file mode 100644
index 0000000..2e9d223
--- /dev/null
+++ b/tools/d2c/bits/decl.h
@@ -0,0 +1,37 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * decl.h - déclarations de prototypes utiles
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _TOOLS_D2C_BITS_DECL_H
+#define _TOOLS_D2C_BITS_DECL_H
+
+
+#include "manager.h"
+
+
+
+/* Interprête des données relatives à un champ de bits. */
+bool load_bits_from_raw_line(coding_bits *, unsigned int, const char *);
+
+
+
+#endif  /* _TOOLS_D2C_BITS_DECL_H */
diff --git a/tools/d2c/bits/grammar.y b/tools/d2c/bits/grammar.y
new file mode 100644
index 0000000..a5d0de7
--- /dev/null
+++ b/tools/d2c/bits/grammar.y
@@ -0,0 +1,117 @@
+
+%{
+
+#include "tokens.h"
+
+
+/* Affiche un message d'erreur suite à l'analyse en échec. */
+static int yyerror(coding_bits *, char *);
+
+%}
+
+
+%code requires {
+
+#include "decl.h"
+
+}
+
+
+%union {
+
+    char *string;                           /* Chaîne de caractères        */
+    int integer;                            /* Valeur numérique entière    */
+
+}
+
+
+%define api.pure full
+
+%parse-param { coding_bits *bits }
+
+%code provides {
+
+#define YY_DECL \
+    int bits_lex(YYSTYPE *yylvalp)
+
+YY_DECL;
+
+}
+
+
+%token NAME SIZE BIT
+
+%type <string> NAME
+%type <integer> SIZE BIT
+
+
+%%
+
+
+bitfield : /* empty */
+         | NAME SIZE bitfield   { register_named_field_in_bits(bits, $1, $2); }
+         | BIT bitfield         { register_bit_in_bits(bits, $1); }
+
+
+%%
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bits = structure impliquée dans le processus.                *
+*                msg  = message d'erreur.                                     *
+*                                                                             *
+*  Description : Affiche un message d'erreur suite à l'analyse en échec.      *
+*                                                                             *
+*  Retour      : 0                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int yyerror(coding_bits *bits, char *msg)
+{
+	printf("bits yyerror line %d: %s\n", yyget_lineno(), msg);
+
+	return 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bits     = structure à constituer à partir de données lues.  *
+*                expected = nombre de bits définis à attendre.                *
+*                raw      = données brutes à analyser.                        *
+*                                                                             *
+*  Description : Interprête des données relatives à un champ de bits.         *
+*                                                                             *
+*  Retour      : true si l'opération s'est bien déroulée, false sinon.        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool load_bits_from_raw_line(coding_bits *bits, unsigned int expected, const char *raw)
+{
+    bool result;                            /* Bilan à faire remonter      */
+    YY_BUFFER_STATE state;                  /* Support d'analyse           */
+    int status;                             /* Bilan de l'analyse          */
+
+    state = yy_scan_string(raw);
+
+    status = yyparse(bits);
+
+    result = (status == 0);
+
+    yy_delete_buffer(state);
+
+    if (result && count_coded_bits(bits) != expected)
+    {
+        fprintf(stderr, "Unexpected word size: %u vs %u\n", count_coded_bits(bits), expected);
+        result = false;
+    }
+
+    return result;
+
+}
diff --git a/tools/d2c/bits/manager.c b/tools/d2c/bits/manager.c
new file mode 100644
index 0000000..db6392d
--- /dev/null
+++ b/tools/d2c/bits/manager.c
@@ -0,0 +1,383 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * manager.c - compréhension et manipulation des champs de bits
+ *
+ * Copyright (C) 2014 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "manager.h"
+
+
+#include <assert.h>
+#include <inttypes.h>
+#include <malloc.h>
+#include <stdint.h>
+#include <string.h>
+
+
+#include "../helpers.h"
+
+
+
+/* --------------------------- GESTION DES CHAMPS DE BITS --------------------------- */
+
+
+/* Elément d'un mot décodé */
+struct _raw_bitfield
+{
+    char *name;                             /* Désignation humaine         */
+    unsigned int start;                     /* Position de départ          */
+    unsigned int length;                    /* Taille du champ             */
+
+    bool used;                              /* Champ défini & utilisé      */
+
+};
+
+
+
+
+/* Représentation de l'ensemble des bits de codage */
+struct _coding_bits
+{
+    raw_bitfield *fields;                   /* Champs de bits détectés     */
+    size_t bf_count;                        /* Nombre de ces champs        */
+    uint64_t bits;                          /* Bits invariables            */
+    uint64_t mask;                          /* Emplacement de ces bits     */
+    unsigned int curpos;                    /* Position pendant l'analyse  */
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : field = champ de bits à consulter.                           *
+*                                                                             *
+*  Description : Indique le nombre de bits utilisés par le champ.             *
+*                                                                             *
+*  Retour      : Nombre de bits considérés.                                   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+unsigned int get_raw_bitfield_length(const raw_bitfield *field)
+{
+    return field->length;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : field = champ de bits à traiter.                             *
+*                                                                             *
+*  Description : Marque un champ de bits comme étant utile.                   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void mark_raw_bitfield_as_used(raw_bitfield *field)
+{
+    field->used = true;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée un nouveau gestionnaire des bits d'encodage brut.       *
+*                                                                             *
+*  Retour      : Nouvelle structure prête à emploi.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+coding_bits *create_coding_bits(void)
+{
+    coding_bits *result;                    /* Définition vierge à renvoyer*/
+
+    result = (coding_bits *)calloc(1, sizeof(coding_bits));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bits = gestionnaire d'un ensemble de bits à libérer.         *
+*                                                                             *
+*  Description : Supprime de la mémoire un gestionnaire de bits d'encodage.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void delete_coding_bits(coding_bits *bits)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < bits->bf_count; i++)
+        free(bits->fields[i].name);
+
+    if (bits->fields != NULL)
+        free(bits->fields);
+
+    free(bits);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bits   = gestionnaire de bits d'encodage brut à consulter.   *
+*                name   = désignation humaine du champ remarqué.              *
+*                length = taille du champ à mémoriser.                        *
+*                                                                             *
+*  Description : Note la présence d'un champ remarquable dans une définition. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void register_named_field_in_bits(coding_bits *bits, char *name, unsigned int length)
+{
+    raw_bitfield *field;                    /* Nouveau champ à constituer  */
+
+    assert((bits->curpos + length) < 64);
+
+    bits->fields = (raw_bitfield *)realloc(bits->fields,
+                                              ++bits->bf_count * sizeof(raw_bitfield));
+
+    field = &bits->fields[bits->bf_count - 1];
+
+    field->name = make_string_lower(name);
+    field->start = bits->curpos;
+    field->length = length;
+
+    bits->curpos += length;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bits = gestionnaire de bits d'encodage brut à consulter.     *
+*                val  = valeur du bit à prendre en compte.                    *
+*                                                                             *
+*  Description : Note la présence d'un bit invariable dans une définition.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void register_bit_in_bits(coding_bits *bits, int val)
+{
+    assert(bits->curpos < 64);
+
+    bits->bits |= (val ? 1 : 0) << bits->curpos;
+    bits->mask |= 1 << bits->curpos;
+
+    bits->curpos++;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bits = gestionnaire de bits d'encodage brut à consulter.     *
+*                                                                             *
+*  Description : Indique le nombre de bits traités.                           *
+*                                                                             *
+*  Retour      : Quantité, positive ou nulle.                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+unsigned int count_coded_bits(const coding_bits *bits)
+{
+    return bits->curpos;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bits = gestionnaire d'encodage brut à consulter.             *
+*                name = désignation humaine du champ à retrouver.             *
+*                                                                             *
+*  Description : Recherche un champ donné dans un ensemble de champs de bits. *
+*                                                                             *
+*  Retour      : Structure associée au champ trouvé ou NULL en cas d'échec.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+raw_bitfield *find_named_field_in_bits(const coding_bits *bits, const char *name)
+{
+    raw_bitfield *result;                   /* Champ de bits à retourner   */
+    size_t i;                               /* Boucle de parcours          */
+
+    result = NULL;
+
+    for (i = 0; i < bits->bf_count && result == NULL; i++)
+        if (strcmp(bits->fields[i].name, name) == 0)
+            result = &bits->fields[i];
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : spec    = spécification servant de base à l'opération.       *
+*                fd      = descripteur d'un flux ouvert en écriture.          *
+*                wide    = taille des mots manipulés (en bits).               *
+*                                                                             *
+*  Description : Déclare les variables C associées aux champs de bits.        *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool declare_used_bits_fields(const coding_bits *bits, int fd, unsigned int wide)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < bits->bf_count; i++)
+        if (bits->fields[i].used)
+            dprintf(fd, "\t\tuint%u_t raw_%s;\n", wide, bits->fields[i].name);
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : spec    = spécification servant de base à l'opération.       *
+*                fd      = descripteur d'un flux ouvert en écriture.          *
+*                                                                             *
+*  Description : Vérifie que les bits fixes correspondent au masque attendu.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool check_bits_correctness(const coding_bits *bits, int fd)
+{
+    switch (bits->curpos)
+    {
+        case 8:
+            dprintf(fd, "\t\tif ((raw & 0x%" PRIx8 ") != 0x%" PRIx8 ") return NULL;\n",
+                    (uint8_t)bits->mask, (uint8_t)bits->bits);
+            break;
+
+        case 16:
+            dprintf(fd, "\t\tif ((raw & 0x%" PRIx16 ") != 0x%" PRIx16 ") return NULL;\n",
+                    (uint16_t)bits->mask, (uint16_t)bits->bits);
+            break;
+
+        case 32:
+            dprintf(fd, "\t\tif ((raw & 0x%" PRIx32 ") != 0x%" PRIx32 ") return NULL;\n",
+                    (uint32_t)bits->mask, (uint32_t)bits->bits);
+            break;
+
+        case 64:
+            dprintf(fd, "\t\tif ((raw & 0x%" PRIx64 ") != 0x%" PRIx64 ") return NULL;\n",
+                    bits->mask, bits->bits);
+            break;
+
+    }
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : spec    = spécification servant de base à l'opération.       *
+*                fd      = descripteur d'un flux ouvert en écriture.          *
+*                                                                             *
+*  Description : Définit les variables C associées aux champs de bits.        *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool define_used_bits_fields(const coding_bits *bits, int fd)
+{
+    size_t i;                               /* Boucle de parcours          */
+    raw_bitfield *rf;                       /* Accès confortable à un champ*/
+
+    for (i = 0; i < bits->bf_count; i++)
+    {
+        rf = &bits->fields[i];
+        if (!rf->used) continue;
+
+        dprintf(fd, "\t\traw_%s = (_raw >> %u) & 0x%llx;\n", rf->name, rf->start, (1ull << rf->length) - 1);
+
+    }
+
+    return true;
+
+}
diff --git a/tools/d2c/bits/manager.h b/tools/d2c/bits/manager.h
new file mode 100644
index 0000000..3269d69
--- /dev/null
+++ b/tools/d2c/bits/manager.h
@@ -0,0 +1,87 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * manager.h - prototypes pour la compréhension et la manipulation des champs de bits
+ *
+ * Copyright (C) 2014 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _TOOLS_D2C_BITS_MANAGER_H
+#define _TOOLS_D2C_BITS_MANAGER_H
+
+
+#include <stdbool.h>
+
+
+
+
+/* --------------------------- GESTION DES CHAMPS DE BITS --------------------------- */
+
+
+/* Elément d'un mot décodé */
+typedef struct _raw_bitfield raw_bitfield;
+
+
+
+/* Indique le nombre de bits utilisés par le champ. */
+unsigned int get_raw_bitfield_length(const raw_bitfield *);
+
+/* Marque un champ de bits comme étant utile. */
+void mark_raw_bitfield_as_used(raw_bitfield *);
+
+
+
+
+
+/* Représentation de l'ensemble des bits de codage */
+typedef struct _coding_bits coding_bits;
+
+
+
+/* Crée un nouveau gestionnaire des bits d'encodage brut. */
+coding_bits *create_coding_bits(void);
+
+/* Supprime de la mémoire un gestionnaire de bits d'encodage. */
+void delete_coding_bits(coding_bits *);
+
+
+
+/* Note la présence d'un champ remarquable dans une définition. */
+void register_named_field_in_bits(coding_bits *, char *, unsigned int);
+
+/* Note la présence d'un bit invariable dans une définition. */
+void register_bit_in_bits(coding_bits *, int);
+
+/* Indique le nombre de bits traités. */
+unsigned int count_coded_bits(const coding_bits *);
+
+/* Recherche un champ donné dans un ensemble de champs de bits. */
+raw_bitfield *find_named_field_in_bits(const coding_bits *, const char *);
+
+/* Déclare les variables C associées aux champs de bits. */
+bool declare_used_bits_fields(const coding_bits *, int, unsigned int);
+
+/* Vérifie que les bits fixes correspondent au masque attendu. */
+bool check_bits_correctness(const coding_bits *, int);
+
+/* Définit les variables C associées aux champs de bits. */
+bool define_used_bits_fields(const coding_bits *, int);
+
+
+
+#endif  /* _TOOLS_D2C_BITS_MANAGER_H */
diff --git a/tools/d2c/bits/tokens.l b/tools/d2c/bits/tokens.l
new file mode 100644
index 0000000..99fb96d
--- /dev/null
+++ b/tools/d2c/bits/tokens.l
@@ -0,0 +1,33 @@
+
+%top {
+
+#include "grammar.h"
+
+}
+
+
+%option noyywrap
+%option nounput
+%option noinput
+%option yylineno
+%option stack
+%option noyy_top_state
+
+%x bsize
+
+
+%%
+
+
+" "                     { }
+
+[A-Za-z_][A-Za-z0-9_]*  { yylvalp->string = strdup(yytext); return NAME; }
+
+"("                     { yy_push_state(bsize); }
+<bsize>[0-9]+           { yylvalp->integer = atoi(yytext); return SIZE; }
+<bsize>")"              { yy_pop_state(); }
+
+[01]                    { yylvalp->integer = atoi(yytext); return BIT; }
+
+
+%%
diff --git a/tools/d2c/coder.c b/tools/d2c/coder.c
index c709bcf..83910aa 100644
--- a/tools/d2c/coder.c
+++ b/tools/d2c/coder.c
@@ -181,8 +181,27 @@ bool do_basic_checks_with_coder(const rented_coder *coder)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : coder  = gestion par la machine en remplacement de l'humain. *
-*                outdir = fichier de définitions à venir lire.                *
+*  Paramètres  : coder = gestion par la machine en remplacement de l'humain.  *
+*                                                                             *
+*  Description : Indique le fichier de définition considéré en entrée.        *
+*                                                                             *
+*  Retour      : Fichier de définition à interpréter.                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *get_coder_input_file(const rented_coder *coder)
+{
+    return coder->input;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : coder = gestion par la machine en remplacement de l'humain.  *
+*                input = fichier de définitions à venir lire.                 *
 *                                                                             *
 *  Description : Spécifie le fichier de définition à prendre en entrée.       *
 *                                                                             *
diff --git a/tools/d2c/coder.h b/tools/d2c/coder.h
index aadb2d4..d9f0f0e 100644
--- a/tools/d2c/coder.h
+++ b/tools/d2c/coder.h
@@ -21,8 +21,8 @@
  */
 
 
-#ifndef _ARCH_ARM_V7_OPDEFS_CODER_H
-#define _ARCH_ARM_V7_OPDEFS_CODER_H
+#ifndef _TOOLS_D2C_CODER_H
+#define _TOOLS_D2C_CODER_H
 
 
 #include <stdbool.h>
@@ -50,6 +50,9 @@ void delete_coder(rented_coder *);
 /* Détermine si les propriétés de base d'un codeur sont là. */
 bool do_basic_checks_with_coder(const rented_coder *);
 
+/* Indique le fichier de définition considéré en entrée. */
+const char *get_coder_input_file(const rented_coder *);
+
 /* Spécifie le fichier de définition à prendre en entrée. */
 void set_coder_input_file(rented_coder *, const char *);
 
@@ -125,4 +128,4 @@ bool dump_all_routines_using_coder(const rented_coder *);
 
 
 
-#endif  /* _ARCH_ARM_V7_OPDEFS_CODER_H */
+#endif  /* _TOOLS_D2C_CODER_H */
diff --git a/tools/d2c/conv.c b/tools/d2c/conv.c
deleted file mode 100644
index 3fae6df..0000000
--- a/tools/d2c/conv.c
+++ /dev/null
@@ -1,518 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * conv.c - substitutions de valeurs depuis un contenu binaire
- *
- * Copyright (C) 2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  OpenIDA is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  OpenIDA is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "conv.h"
-
-
-#include <assert.h>
-#include <ctype.h>
-#include <malloc.h>
-#include <stdbool.h>
-#include <string.h>
-
-
-#include "helpers.h"
-#include "qckcall.h"
-
-
-
-/* ---------------------------- CONVERSION DES ARGUMENTS ---------------------------- */
-
-
-/* Fonction de conversion */
-struct _conv_func
-{
-    bool declared;                          /* Expression déjà déclarée ?  */
-    bool defined;                           /* Expression déjà définie ?   */
-
-    char *dest;                             /* Variable de destination     */
-
-    bool is_expr;                           /* Choix du contenu réel       */
-
-    union
-    {
-        arg_expr_t *expr;                   /* Valeur expressive directe   */
-
-        struct
-        {
-            char *name;                     /* Fonction de conversion      */
-            arg_list_t *args;               /* Liste des arguments         */
-
-        };
-
-    };
-
-};
-
-
-
-/* ---------------------------- ENSEMBLES DE CONVERSIONS ---------------------------- */
-
-
-/* Liste des fonctions de conversions présentes */
-struct _conv_list
-{
-    conv_func **functions;                 /* Fonctions de conversion     */
-    size_t func_count;                     /* Nombre de ces fonctions     */
-
-};
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                              CONVERSION DES ARGUMENTS                              */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : dest = désignation de la variable de destination.            *
-*                expr = expression dont la valeur est à assigner.             *
-*                                                                             *
-*  Description : Définit une conversion à partir d'une simple expression.     *
-*                                                                             *
-*  Retour      : Structure mise en place.                                     *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-conv_func *make_conv_from_expr(char *dest, arg_expr_t *expr)
-{
-    conv_func *result;                      /* Conversion à retourner      */
-
-    result = (conv_func *)calloc(1, sizeof(conv_func));
-
-    result->dest = make_string_lower(dest);
-
-    result->is_expr = true;
-    result->expr = expr;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : dest = désignation de la variable de destination.            *
-*                func = nom de la fonction assurant le calcul de valeur.      *
-*                args = argument(s) à fournir à cette fonction.               *
-*                                                                             *
-*  Description : Définit une conversion à partir d'une function à appeler.    *
-*                                                                             *
-*  Retour      : Structure mise en place.                                     *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-conv_func *make_conv_from_func(char *dest, char *func, arg_list_t *args)
-{
-    conv_func *result;                      /* Conversion à retourner      */
-
-    result = (conv_func *)calloc(1, sizeof(conv_func));
-
-    result->dest = make_string_lower(dest);
-
-    result->is_expr = false;
-    result->name = func;
-    result->args = args;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : func = éléments de conversion à supprimer de la mémoire.     *
-*                                                                             *
-*  Description : Libère de la mémoire une conversion enregistrée.             *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void delete_conv_func(conv_func *func)
-{
-    if (func->is_expr)
-        delete_arg_expr(func->expr);
-
-    else
-    {
-        free(func->name);
-        delete_arg_list(func->args);
-    }
-
-    free(func);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : func = fonction de conversion à consulter.                   *
-*                                                                             *
-*  Description : Indique la variable de destination d'une conversion.         *
-*                                                                             *
-*  Retour      : Désignation humaine de la variable de destination.           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-const char *get_conv_dest_name(const conv_func *func)
-{
-    return func->dest;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : func = fonction de conversion à consulter.                   *
-*                                                                             *
-*  Description : Indique la nature d'une conversion : fonction ou expression ?*
-*                                                                             *
-*  Retour      : Indication sur la constitution interne de la conversion.     *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool is_conv_func_expression(const conv_func *func)
-{
-    return func->is_expr;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : func = fonction de conversion à consulter.                   *
-*                bits = gestionnaire des bits d'encodage.                     *
-*                list = liste de l'ensemble des fonctions de conversion.      *
-*                size = taille déterminée avec précision. [OUT]               *
-*                                                                             *
-*  Description : Détermine la taille en bits du résultat d'une fonction.      *
-*                                                                             *
-*  Retour      : true si la taille a pu être déterminée, false sinon.         *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool compute_conv_func_size(const conv_func *func, const coding_bits *bits, const conv_list *list, unsigned int *size)
-{
-    bool result;                            /* Bilan à retourner           */
-
-    result = func->is_expr;
-
-    if (result)
-        result = compute_arg_expr_size(func->expr, bits, list, size);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : func = fonction de conversion à manipuler.                   *
-*                bits = gestionnaire des bits d'encodage.                     *
-*                list = liste de l'ensemble des fonctions de conversion.      *
-*                                                                             *
-*  Description : Marque les champs utilisés par une fonction de conversion.   *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool mark_conv_func(conv_func *func, const coding_bits *bits, const conv_list *list)
-{
-    bool result;                            /* Bilan à remonter            */
-
-    if (func->is_expr)
-        result = ensure_arg_expr_content_fully_marked(func->expr, bits, list);
-    else
-        result = ensure_arg_list_content_fully_marked(func->args, bits, list);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : func = fonction de conversion à manipuler.                   *
-*                fd   = descripteur d'un flux ouvert en écriture.             *
-*                bits = gestionnaire des bits d'encodage.                     *
-*                list = liste de l'ensemble des fonctions de conversion.      *
-*                wide = taille des mots décodés.                              *
-*                                                                             *
-*  Description : Déclare les variables associées à une fonction de conversion.*
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool declare_conv_func(conv_func *func, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide)
-{
-    bool result;                            /* Bilan à remonter            */
-
-    /* Si la fonction a déjà été définie lors d'un précédent besoin... */
-    if (func->declared) return true;
-
-    if (func->is_expr)
-        result = ensure_arg_expr_content_fully_declared(func->expr, fd, bits, list, wide);
-
-    else
-        result = ensure_arg_list_content_fully_declared(func->args, fd, bits, list, wide);
-
-    func->declared = result;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : func     = fonction de conversion à manipuler.               *
-*                last     = précise si la conversion est la dernière.         *
-*                internal = indique le type de manipulation finale.           *
-*                fd       = descripteur d'un flux ouvert en écriture.         *
-*                arch     = architecture visée par l'opération globale.       *
-*                bits     = gestionnaire des bits d'encodage.                 *
-*                list     = liste de l'ensemble des fonctions de conversion.  *
-*                pp       = pré-processeur pour les échanges de chaînes.      *
-*                                                                             *
-*  Description : Définit les variables associées à une fonction de conversion.*
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool define_conv_func(conv_func *func, bool last, bool internal, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp)
-{
-    bool result;                            /* Bilan à remonter            */
-    const char *callable;                   /* Fonction à appeler          */
-
-    /* Si la fonction a déjà été définie lors d'un précédent besoin... */
-    if (func->defined) return true;
-
-    if (func->is_expr)
-        result = ensure_arg_expr_content_fully_defined(func->expr, fd, arch, bits, list, pp);
-    else
-        result = ensure_arg_list_content_fully_defined(func->args, fd, arch, bits, list, pp);
-
-    /* Nom de la fonction effectivement appelée */
-
-    if (!func->is_expr)
-    {
-        callable = find_macro(pp, func->name);
-
-        if (callable == NULL)
-            callable = func->name;
-
-    }
-    else callable = NULL;
-
-    if (last && callable == NULL)
-    {
-        fprintf(stderr, "Error: expected function to store '%s'.\n", func->dest);
-        return false;
-    }
-
-    /* Dernier niveau : la variable de destination est imposée ! */
-    if (last)
-    {
-        /* Si l'on doit manipuler une propriété d'instructon... */
-        if (internal)
-            result = checked_call_instr_func(callable, func->args, fd, bits, list, pp);
-
-        /* Si on doit constituer un opérande à ajouter... */
-        else
-        {
-            if (strchr(callable, '(') == NULL)
-                dprintf(fd, "\t\top = %s(", callable);
-            else
-                dprintf(fd, "\t\top = %s", callable);
-
-            result &= define_arg_list(func->args, fd, bits, list);
-
-            dprintf(fd, ");\n");
-
-        }
-
-    }
-
-    /* On constitue une variable intermédiaire, dont on peut conserver le nom ! */
-    else
-    {
-        dprintf(fd, "\t\tval_%s = ", func->dest);
-
-        if (func->is_expr)
-            result &= define_arg_expr(func->expr, fd, bits, list);
-
-        else
-        {
-            dprintf(fd, "%s(", callable);
-
-            result = define_arg_list(func->args, fd, bits, list);
-
-            dprintf(fd, ")");
-
-        }
-
-        dprintf(fd, ";\n");
-
-    }
-
-    func->defined = result;
-
-    return result;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                              ENSEMBLES DE CONVERSIONS                              */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : -                                                            *
-*                                                                             *
-*  Description : Crée un nouvelle liste vierge de fonctions de conversion.    *
-*                                                                             *
-*  Retour      : Nouvelle structure prête à emploi.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-conv_list *create_conv_list(void)
-{
-    conv_list *result;                       /* Définition vierge à renvoyer*/
-
-    result = (conv_list *)calloc(1, sizeof(conv_list));
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : list = ensemble de fonctions de conversion à supprimer.      *
-*                                                                             *
-*  Description : Supprime de la mémoire une de fonctions de conversion.       *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void delete_conv_list(conv_list *list)
-{
-    size_t i;                               /* Boucle de parcours          */
-
-    for (i = 0; i < list->func_count; i++)
-        delete_conv_func(list->functions[i]);
-
-    if (list->functions != NULL)
-        free(list->functions);
-
-    free(list);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : list = liste de fonctions de conversion à compléter.         *
-*                func = nom de la fonction assurant le calcul de valeur.      *
-*                                                                             *
-*  Description : Enregistre une function de conversion du brut à l'utile.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void register_conversion(conv_list *list, conv_func *func)
-{
-    list->functions = (conv_func **)realloc(list->functions, ++list->func_count * sizeof(conv_func *));
-
-    list->functions[list->func_count - 1] = func;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : list = liste de fonctions de conversion à consulter.         *
-*                name = désignation humaine du champ à retrouver.             *
-*                                                                             *
-*  Description : Recherche un résultat précis dans une liste de fonctions.    *
-*                                                                             *
-*  Retour      : Structure associée au résulat trouvé ou NULL en cas d'échec. *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-conv_func *find_named_conv_in_list(const conv_list *list, const char *name)
-{
-    conv_func *result;                      /* Fonction à retourner        */
-    size_t i;                               /* Boucle de parcours          */
-    const char *dest;                       /* Nom de variable existante   */
-
-    result = NULL;
-
-    for (i = 0; i < list->func_count && result == NULL; i++)
-    {
-        dest = get_conv_dest_name(list->functions[i]);
-
-        if (strcmp(dest, name) == 0)
-            result = list->functions[i];
-
-    }
-
-    return result;
-
-}
diff --git a/tools/d2c/conv.h b/tools/d2c/conv.h
deleted file mode 100644
index 85c7578..0000000
--- a/tools/d2c/conv.h
+++ /dev/null
@@ -1,94 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * conv.h - prototypes pour les substitutions de valeurs depuis un contenu binaire
- *
- * Copyright (C) 2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  OpenIDA is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  OpenIDA is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _TOOLS_CONV_H
-#define _TOOLS_CONV_H
-
-
-#include <stdbool.h>
-
-
-#include "args.h"
-#include "bits.h"
-#include "pproc.h"
-
-
-
-/* ---------------------------- CONVERSION DES ARGUMENTS ---------------------------- */
-
-
-/* Fonction de conversion */
-typedef struct _conv_func conv_func;
-
-
-/* Définit une conversion à partir d'une simple expression. */
-conv_func *make_conv_from_expr(char *, arg_expr_t *);
-
-/* Définit une conversion à partir d'une function à appeler. */
-conv_func *make_conv_from_func(char *, char *, arg_list_t *);
-
-/* Libère de la mémoire une conversion enregistrée. */
-void delete_conv_func(conv_func *);
-
-/* Indique la variable de destination d'une conversion. */
-const char *get_conv_dest_name(const conv_func *);
-
-/* Indique la nature d'une conversion : fonction ou expression ? */
-bool is_conv_func_expression(const conv_func *);
-
-/* Détermine la taille en bits du résultat d'une fonction. */
-bool compute_conv_func_size(const conv_func *, const coding_bits *, const conv_list *, unsigned int *);
-
-/* Marque les champs utilisés par une fonction de conversion. */
-bool mark_conv_func(conv_func *, const coding_bits *, const conv_list *);
-
-/* Déclare les variables associées à une fonction de conversion. */
-bool declare_conv_func(conv_func *, int, const coding_bits *, const conv_list *, unsigned int);
-
-/* Définit les variables associées à une fonction de conversion. */
-bool define_conv_func(conv_func *, bool, bool, int, const char *, const coding_bits *, const conv_list *, const pre_processor *);
-
-
-
-/* ---------------------------- ENSEMBLES DE CONVERSIONS ---------------------------- */
-
-
-/* Liste des fonctions de conversions présentes */
-typedef struct _conv_list conv_list;
-
-
-/* Crée un nouvelle liste vierge de fonctions de conversion. */
-conv_list *create_conv_list(void);
-
-/* Supprime de la mémoire une de fonctions de conversion. */
-void delete_conv_list(conv_list *);
-
-/* Enregistre une function de conversion du brut à l'utile. */
-void register_conversion(conv_list *, conv_func *);
-
-/* Recherche un résultat précis dans une liste de fonctions. */
-conv_func *find_named_conv_in_list(const conv_list *, const char *);
-
-
-
-#endif  /* _TOOLS_CONV_H */
diff --git a/tools/d2c/conv/Makefile.am b/tools/d2c/conv/Makefile.am
new file mode 100644
index 0000000..7744bc0
--- /dev/null
+++ b/tools/d2c/conv/Makefile.am
@@ -0,0 +1,31 @@
+
+BUILT_SOURCES = grammar.h
+
+
+# On évite d'utiliser les variables personnalisées de type *_la_[YL]FLAGS
+# afin de conserver des noms de fichiers simples, ie sans le nom de la
+# bibliothèque de sortie en préfixe.
+
+AM_YFLAGS = -v -d -p conv_
+
+AM_LFLAGS = -P conv_ -o lex.yy.c --header-file=tokens.h			\
+			-Dyylval=conv_lval -Dyyget_lineno=conv_get_lineno 	\
+			-Dyy_scan_string=conv__scan_string					\
+			-Dyy_delete_buffer=conv__delete_buffer
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS)
+
+
+noinst_LTLIBRARIES  = libd2cconv.la
+
+.NOTPARALLEL: $(noinst_LTLIBRARIES)
+
+libd2cconv_la_SOURCES =					\
+	decl.h								\
+	manager.h manager.c					\
+	tokens.l							\
+	grammar.y
+
+
+# Automake fait les choses à moitié
+CLEANFILES = grammar.h grammar.c grammar.output tokens.c tokens.h
diff --git a/tools/d2c/conv/decl.h b/tools/d2c/conv/decl.h
new file mode 100644
index 0000000..e1388fe
--- /dev/null
+++ b/tools/d2c/conv/decl.h
@@ -0,0 +1,37 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * decl.h - déclarations de prototypes utiles
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _TOOLS_D2C_CONV_DECL_H
+#define _TOOLS_D2C_CONV_DECL_H
+
+
+#include "manager.h"
+
+
+
+/* Interprête des données relatives à un bloc de conversions. */
+bool load_convs_from_raw_block(conv_list *, const char *);
+
+
+
+#endif  /* _TOOLS_D2C_CONV_DECL_H */
diff --git a/tools/d2c/conv/grammar.y b/tools/d2c/conv/grammar.y
new file mode 100644
index 0000000..71fcc47
--- /dev/null
+++ b/tools/d2c/conv/grammar.y
@@ -0,0 +1,130 @@
+
+%{
+
+#include "tokens.h"
+
+
+/* Affiche un message d'erreur suite à l'analyse en échec. */
+static int yyerror(conv_list *, char *);
+
+%}
+
+
+%code requires {
+
+#include "decl.h"
+#include "../args/decl.h"
+
+}
+
+
+%union {
+
+    char *string;                           /* Chaîne de caractères #1     */
+    const char *cstring;                    /* Chaîne de caractères #2     */
+
+    conv_func *subst;                       /* Fonction de conversion      */
+
+}
+
+
+%define api.pure full
+
+%parse-param { conv_list *list }
+
+%code provides {
+
+#define YY_DECL \
+    int conv_lex(YYSTYPE *yylvalp)
+
+YY_DECL;
+
+}
+
+
+%token NAME
+%token EQ
+%token RAW_LINE
+
+%type <string> NAME
+%type <cstring> RAW_LINE
+
+%type <subst> substitution
+
+
+%%
+
+
+substitutions : /* empty */
+              | substitutions substitution { register_conversion(list, $2); }
+
+substitution : NAME EQ RAW_LINE {
+                                    right_op_t rop;
+                                    bool status;
+
+                                    status = load_args_from_raw_line(&rop, $3);
+                                    if (!status) YYABORT;
+
+                                    if (rop.func == NULL)
+                                        $$ = make_conv_from_expr($1, rop.expr);
+                                    else
+                                        $$ = make_conv_from_func($1, rop.func, rop.args);
+
+                                }
+
+
+%%
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list = structure impliquée dans le processus.                *
+*                msg  = message d'erreur.                                     *
+*                                                                             *
+*  Description : Affiche un message d'erreur suite à l'analyse en échec.      *
+*                                                                             *
+*  Retour      : 0                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int yyerror(conv_list *list, char *msg)
+{
+	printf("yyerror line %d: %s\n", yyget_lineno(), msg);
+
+	return 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list = structure à constituer à partir de données lues.      *
+*                raw  = données brutes à analyser.                            *
+*                                                                             *
+*  Description : Interprête des données relatives à un bloc de conversions.   *
+*                                                                             *
+*  Retour      : true si l'opération s'est bien déroulée, false sinon.        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool load_convs_from_raw_block(conv_list *list, const char *raw)
+{
+    bool result;                            /* Bilan à faire remonter      */
+    YY_BUFFER_STATE state;                  /* Support d'analyse           */
+    int status;                             /* Bilan de l'analyse          */
+
+    state = yy_scan_string(raw);
+
+    status = yyparse(list);
+
+    result = (status == 0);
+
+    yy_delete_buffer(state);
+
+    return result;
+
+}
diff --git a/tools/d2c/conv/manager.c b/tools/d2c/conv/manager.c
new file mode 100644
index 0000000..c04a49e
--- /dev/null
+++ b/tools/d2c/conv/manager.c
@@ -0,0 +1,518 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * manager.c - substitutions de valeurs depuis un contenu binaire
+ *
+ * Copyright (C) 2014 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "manager.h"
+
+
+#include <assert.h>
+#include <ctype.h>
+#include <malloc.h>
+#include <stdbool.h>
+#include <string.h>
+
+
+#include "../helpers.h"
+#include "../qckcall.h"
+
+
+
+/* ---------------------------- CONVERSION DES ARGUMENTS ---------------------------- */
+
+
+/* Fonction de conversion */
+struct _conv_func
+{
+    bool declared;                          /* Expression déjà déclarée ?  */
+    bool defined;                           /* Expression déjà définie ?   */
+
+    char *dest;                             /* Variable de destination     */
+
+    bool is_expr;                           /* Choix du contenu réel       */
+
+    union
+    {
+        arg_expr_t *expr;                   /* Valeur expressive directe   */
+
+        struct
+        {
+            char *name;                     /* Fonction de conversion      */
+            arg_list_t *args;               /* Liste des arguments         */
+
+        };
+
+    };
+
+};
+
+
+
+/* ---------------------------- ENSEMBLES DE CONVERSIONS ---------------------------- */
+
+
+/* Liste des fonctions de conversions présentes */
+struct _conv_list
+{
+    conv_func **functions;                 /* Fonctions de conversion     */
+    size_t func_count;                     /* Nombre de ces fonctions     */
+
+};
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                              CONVERSION DES ARGUMENTS                              */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : dest = désignation de la variable de destination.            *
+*                expr = expression dont la valeur est à assigner.             *
+*                                                                             *
+*  Description : Définit une conversion à partir d'une simple expression.     *
+*                                                                             *
+*  Retour      : Structure mise en place.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+conv_func *make_conv_from_expr(char *dest, arg_expr_t *expr)
+{
+    conv_func *result;                      /* Conversion à retourner      */
+
+    result = (conv_func *)calloc(1, sizeof(conv_func));
+
+    result->dest = make_string_lower(dest);
+
+    result->is_expr = true;
+    result->expr = expr;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : dest = désignation de la variable de destination.            *
+*                func = nom de la fonction assurant le calcul de valeur.      *
+*                args = argument(s) à fournir à cette fonction.               *
+*                                                                             *
+*  Description : Définit une conversion à partir d'une function à appeler.    *
+*                                                                             *
+*  Retour      : Structure mise en place.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+conv_func *make_conv_from_func(char *dest, char *func, arg_list_t *args)
+{
+    conv_func *result;                      /* Conversion à retourner      */
+
+    result = (conv_func *)calloc(1, sizeof(conv_func));
+
+    result->dest = make_string_lower(dest);
+
+    result->is_expr = false;
+    result->name = func;
+    result->args = args;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : func = éléments de conversion à supprimer de la mémoire.     *
+*                                                                             *
+*  Description : Libère de la mémoire une conversion enregistrée.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void delete_conv_func(conv_func *func)
+{
+    if (func->is_expr)
+        delete_arg_expr(func->expr);
+
+    else
+    {
+        free(func->name);
+        delete_arg_list(func->args);
+    }
+
+    free(func);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : func = fonction de conversion à consulter.                   *
+*                                                                             *
+*  Description : Indique la variable de destination d'une conversion.         *
+*                                                                             *
+*  Retour      : Désignation humaine de la variable de destination.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *get_conv_dest_name(const conv_func *func)
+{
+    return func->dest;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : func = fonction de conversion à consulter.                   *
+*                                                                             *
+*  Description : Indique la nature d'une conversion : fonction ou expression ?*
+*                                                                             *
+*  Retour      : Indication sur la constitution interne de la conversion.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool is_conv_func_expression(const conv_func *func)
+{
+    return func->is_expr;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : func = fonction de conversion à consulter.                   *
+*                bits = gestionnaire des bits d'encodage.                     *
+*                list = liste de l'ensemble des fonctions de conversion.      *
+*                size = taille déterminée avec précision. [OUT]               *
+*                                                                             *
+*  Description : Détermine la taille en bits du résultat d'une fonction.      *
+*                                                                             *
+*  Retour      : true si la taille a pu être déterminée, false sinon.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool compute_conv_func_size(const conv_func *func, const coding_bits *bits, const conv_list *list, unsigned int *size)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = func->is_expr;
+
+    if (result)
+        result = compute_arg_expr_size(func->expr, bits, list, size);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : func = fonction de conversion à manipuler.                   *
+*                bits = gestionnaire des bits d'encodage.                     *
+*                list = liste de l'ensemble des fonctions de conversion.      *
+*                                                                             *
+*  Description : Marque les champs utilisés par une fonction de conversion.   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool mark_conv_func(conv_func *func, const coding_bits *bits, const conv_list *list)
+{
+    bool result;                            /* Bilan à remonter            */
+
+    if (func->is_expr)
+        result = ensure_arg_expr_content_fully_marked(func->expr, bits, list);
+    else
+        result = ensure_arg_list_content_fully_marked(func->args, bits, list);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : func = fonction de conversion à manipuler.                   *
+*                fd   = descripteur d'un flux ouvert en écriture.             *
+*                bits = gestionnaire des bits d'encodage.                     *
+*                list = liste de l'ensemble des fonctions de conversion.      *
+*                wide = taille des mots décodés.                              *
+*                                                                             *
+*  Description : Déclare les variables associées à une fonction de conversion.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool declare_conv_func(conv_func *func, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide)
+{
+    bool result;                            /* Bilan à remonter            */
+
+    /* Si la fonction a déjà été définie lors d'un précédent besoin... */
+    if (func->declared) return true;
+
+    if (func->is_expr)
+        result = ensure_arg_expr_content_fully_declared(func->expr, fd, bits, list, wide);
+
+    else
+        result = ensure_arg_list_content_fully_declared(func->args, fd, bits, list, wide);
+
+    func->declared = result;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : func     = fonction de conversion à manipuler.               *
+*                last     = précise si la conversion est la dernière.         *
+*                internal = indique le type de manipulation finale.           *
+*                fd       = descripteur d'un flux ouvert en écriture.         *
+*                arch     = architecture visée par l'opération globale.       *
+*                bits     = gestionnaire des bits d'encodage.                 *
+*                list     = liste de l'ensemble des fonctions de conversion.  *
+*                pp       = pré-processeur pour les échanges de chaînes.      *
+*                                                                             *
+*  Description : Définit les variables associées à une fonction de conversion.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool define_conv_func(conv_func *func, bool last, bool internal, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp)
+{
+    bool result;                            /* Bilan à remonter            */
+    const char *callable;                   /* Fonction à appeler          */
+
+    /* Si la fonction a déjà été définie lors d'un précédent besoin... */
+    if (func->defined) return true;
+
+    if (func->is_expr)
+        result = ensure_arg_expr_content_fully_defined(func->expr, fd, arch, bits, list, pp);
+    else
+        result = ensure_arg_list_content_fully_defined(func->args, fd, arch, bits, list, pp);
+
+    /* Nom de la fonction effectivement appelée */
+
+    if (!func->is_expr)
+    {
+        callable = find_macro(pp, func->name);
+
+        if (callable == NULL)
+            callable = func->name;
+
+    }
+    else callable = NULL;
+
+    if (last && callable == NULL)
+    {
+        fprintf(stderr, "Error: expected function to store '%s'.\n", func->dest);
+        return false;
+    }
+
+    /* Dernier niveau : la variable de destination est imposée ! */
+    if (last)
+    {
+        /* Si l'on doit manipuler une propriété d'instructon... */
+        if (internal)
+            result = checked_call_instr_func(callable, func->args, fd, bits, list, pp);
+
+        /* Si on doit constituer un opérande à ajouter... */
+        else
+        {
+            if (strchr(callable, '(') == NULL)
+                dprintf(fd, "\t\top = %s(", callable);
+            else
+                dprintf(fd, "\t\top = %s", callable);
+
+            result &= define_arg_list(func->args, fd, bits, list);
+
+            dprintf(fd, ");\n");
+
+        }
+
+    }
+
+    /* On constitue une variable intermédiaire, dont on peut conserver le nom ! */
+    else
+    {
+        dprintf(fd, "\t\tval_%s = ", func->dest);
+
+        if (func->is_expr)
+            result &= define_arg_expr(func->expr, fd, bits, list);
+
+        else
+        {
+            dprintf(fd, "%s(", callable);
+
+            result = define_arg_list(func->args, fd, bits, list);
+
+            dprintf(fd, ")");
+
+        }
+
+        dprintf(fd, ";\n");
+
+    }
+
+    func->defined = result;
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                              ENSEMBLES DE CONVERSIONS                              */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée un nouvelle liste vierge de fonctions de conversion.    *
+*                                                                             *
+*  Retour      : Nouvelle structure prête à emploi.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+conv_list *create_conv_list(void)
+{
+    conv_list *result;                       /* Définition vierge à renvoyer*/
+
+    result = (conv_list *)calloc(1, sizeof(conv_list));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list = ensemble de fonctions de conversion à supprimer.      *
+*                                                                             *
+*  Description : Supprime de la mémoire une de fonctions de conversion.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void delete_conv_list(conv_list *list)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < list->func_count; i++)
+        delete_conv_func(list->functions[i]);
+
+    if (list->functions != NULL)
+        free(list->functions);
+
+    free(list);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list = liste de fonctions de conversion à compléter.         *
+*                func = nom de la fonction assurant le calcul de valeur.      *
+*                                                                             *
+*  Description : Enregistre une function de conversion du brut à l'utile.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void register_conversion(conv_list *list, conv_func *func)
+{
+    list->functions = (conv_func **)realloc(list->functions, ++list->func_count * sizeof(conv_func *));
+
+    list->functions[list->func_count - 1] = func;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list = liste de fonctions de conversion à consulter.         *
+*                name = désignation humaine du champ à retrouver.             *
+*                                                                             *
+*  Description : Recherche un résultat précis dans une liste de fonctions.    *
+*                                                                             *
+*  Retour      : Structure associée au résulat trouvé ou NULL en cas d'échec. *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+conv_func *find_named_conv_in_list(const conv_list *list, const char *name)
+{
+    conv_func *result;                      /* Fonction à retourner        */
+    size_t i;                               /* Boucle de parcours          */
+    const char *dest;                       /* Nom de variable existante   */
+
+    result = NULL;
+
+    for (i = 0; i < list->func_count && result == NULL; i++)
+    {
+        dest = get_conv_dest_name(list->functions[i]);
+
+        if (strcmp(dest, name) == 0)
+            result = list->functions[i];
+
+    }
+
+    return result;
+
+}
diff --git a/tools/d2c/conv/manager.h b/tools/d2c/conv/manager.h
new file mode 100644
index 0000000..abd6c6f
--- /dev/null
+++ b/tools/d2c/conv/manager.h
@@ -0,0 +1,94 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * manager.h - prototypes pour les substitutions de valeurs depuis un contenu binaire
+ *
+ * Copyright (C) 2014 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _TOOLS_D2C_CONV_MANAGER_H
+#define _TOOLS_D2C_CONV_MANAGER_H
+
+
+#include <stdbool.h>
+
+
+#include "../pproc.h"
+#include "../args/manager.h"
+#include "../bits/manager.h"
+
+
+
+/* ---------------------------- CONVERSION DES ARGUMENTS ---------------------------- */
+
+
+/* Fonction de conversion */
+typedef struct _conv_func conv_func;
+
+
+/* Définit une conversion à partir d'une simple expression. */
+conv_func *make_conv_from_expr(char *, arg_expr_t *);
+
+/* Définit une conversion à partir d'une function à appeler. */
+conv_func *make_conv_from_func(char *, char *, arg_list_t *);
+
+/* Libère de la mémoire une conversion enregistrée. */
+void delete_conv_func(conv_func *);
+
+/* Indique la variable de destination d'une conversion. */
+const char *get_conv_dest_name(const conv_func *);
+
+/* Indique la nature d'une conversion : fonction ou expression ? */
+bool is_conv_func_expression(const conv_func *);
+
+/* Détermine la taille en bits du résultat d'une fonction. */
+bool compute_conv_func_size(const conv_func *, const coding_bits *, const conv_list *, unsigned int *);
+
+/* Marque les champs utilisés par une fonction de conversion. */
+bool mark_conv_func(conv_func *, const coding_bits *, const conv_list *);
+
+/* Déclare les variables associées à une fonction de conversion. */
+bool declare_conv_func(conv_func *, int, const coding_bits *, const conv_list *, unsigned int);
+
+/* Définit les variables associées à une fonction de conversion. */
+bool define_conv_func(conv_func *, bool, bool, int, const char *, const coding_bits *, const conv_list *, const pre_processor *);
+
+
+
+/* ---------------------------- ENSEMBLES DE CONVERSIONS ---------------------------- */
+
+
+/* Liste des fonctions de conversions présentes */
+typedef struct _conv_list conv_list;
+
+
+/* Crée un nouvelle liste vierge de fonctions de conversion. */
+conv_list *create_conv_list(void);
+
+/* Supprime de la mémoire une de fonctions de conversion. */
+void delete_conv_list(conv_list *);
+
+/* Enregistre une function de conversion du brut à l'utile. */
+void register_conversion(conv_list *, conv_func *);
+
+/* Recherche un résultat précis dans une liste de fonctions. */
+conv_func *find_named_conv_in_list(const conv_list *, const char *);
+
+
+
+#endif  /* _TOOLS_D2C_CONV_MANAGER_H */
diff --git a/tools/d2c/conv/tokens.l b/tools/d2c/conv/tokens.l
new file mode 100644
index 0000000..ef6b958
--- /dev/null
+++ b/tools/d2c/conv/tokens.l
@@ -0,0 +1,32 @@
+
+%top {
+
+#include "grammar.h"
+
+}
+
+
+%option noyywrap
+%option nounput
+%option noinput
+%option yylineno
+%option stack
+%option noyy_top_state
+
+%x raw_line
+
+
+%%
+
+
+[ \t\n]+                { }
+
+[A-Za-z_][A-Za-z0-9_]*  { yylvalp->string = strdup(yytext); return NAME; }
+
+"="                     { yy_push_state(raw_line); return EQ; }
+
+<raw_line>[^\n]+        { yylvalp->cstring = yytext; return RAW_LINE; }
+<raw_line>"\n"          { yy_pop_state(); }
+
+
+%%
diff --git a/tools/d2c/d2c.mk b/tools/d2c/d2c.mk
index 36bb38e..b0b7b92 100644
--- a/tools/d2c/d2c.mk
+++ b/tools/d2c/d2c.mk
@@ -19,7 +19,7 @@ fix_verbose_0 = echo "  FIX     " `basename $$f`;
 SUFFIXES = .g
 
 .d.g:
-	$(d2c_verbose)$(D2C_BIN) -i $< -d $(D2C_OUTDIR) -a $(D2C_ARCH) -H $(D2C_HEADER) $(D2C_ENCODINGS) $(D2C_MACROS) < $<
+	$(d2c_verbose)$(D2C_BIN) -i $< -d $(D2C_OUTDIR) -a $(D2C_ARCH) -H $(D2C_HEADER) $(D2C_ENCODINGS) $(D2C_MACROS)
 	@touch $@
 
 # Merci http://www.commandlinefu.com/commands/view/10276/grep-tab-t
diff --git a/tools/d2c/d2c_gram.y b/tools/d2c/d2c_gram.y
deleted file mode 100644
index 9827b05..0000000
--- a/tools/d2c/d2c_gram.y
+++ /dev/null
@@ -1,472 +0,0 @@
-
-%{
-
-#include <getopt.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-#include "coder.h"
-#include "d2c_tok.h"
-
-
-extern int yylex();
-
-extern void free_flex_memory(void);
-
-
-/* Affiche un message d'erreur suite à l'analyse en échec. */
-static int d2c_error(rented_coder *, char *);
-
-/* Affiche des indications sur l'utilisation du programme. */
-static void show_usage(const char *);
-
-
-%}
-
-
-%code requires {
-
-/* Pour la définition des expressions conditionnelles... */
-#include "coder.h"
-
-#include "conv.h"
-#include "helpers.h"
-
-struct action_tmp
-{
-    CondActionType action;
-    const char *details;
-};
-
-
-#define register_named_field_in_coder(c, n, l)              \
-    ({                                                      \
-        encoding_spec *__spec;                              \
-        coding_bits *__bits;                                \
-        __spec = get_current_encoding_spec(c);              \
-        __bits = get_bits_in_encoding_spec(__spec);         \
-        register_named_field_in_bits(__bits, n, l);         \
-    })
-
-#define register_bit_in_coder(c, v)                         \
-    ({                                                      \
-        encoding_spec *__spec;                              \
-        coding_bits *__bits;                                \
-        __spec = get_current_encoding_spec(c);              \
-        __bits = get_bits_in_encoding_spec(__spec);         \
-        register_bit_in_bits(__bits, v);                    \
-    })
-
-#define count_coder_bits(c)                                 \
-    ({                                                      \
-        encoding_spec *__spec;                              \
-        coding_bits *__bits;                                \
-        __spec = get_current_encoding_spec(c);              \
-        __bits = get_bits_in_encoding_spec(__spec);         \
-        count_coded_bits(__bits);                           \
-    })
-
-#define register_syntax_item_in_coder(c, n, i)              \
-    ({                                                      \
-        encoding_spec *__spec;                              \
-        asm_syntax *__syntax;                               \
-        __spec = get_current_encoding_spec(c);              \
-        __syntax = get_syntax_in_encoding_spec(__spec);     \
-        register_syntax_item(__syntax, n, i);               \
-    })
-
-#define register_conversion_in_coder(c, f)                  \
-    ({                                                      \
-        encoding_spec *__spec;                              \
-        conv_list *__list;                                  \
-        __spec = get_current_encoding_spec(c);              \
-        __list = get_conversions_in_encoding_spec(__spec);  \
-        register_conversion(__list, f);                     \
-    })
-
-#define register_hook_in_coder(c, t, f)                     \
-    ({                                                      \
-        encoding_spec *__spec;                              \
-        instr_hooks *__hooks;;                              \
-        __spec = get_current_encoding_spec(c);              \
-        __hooks = get_hooks_in_encoding_spec(__spec);       \
-        register_hook_function(__hooks, t, f);              \
-    })
-
-#define add_conditional_rule_to_coder(c, e, a)              \
-    ({                                                      \
-        encoding_spec *__spec;                              \
-        decoding_rules *__rules;                            \
-        __spec = get_current_encoding_spec(c);              \
-        __rules = get_rules_in_encoding_spec(__spec);       \
-        register_conditional_rule(__rules, e, a);           \
-    })
-
-}
-
-%union {
-
-    char *string;                           /* Chaîne de caractères #1     */
-    const char *cstring;                    /* Chaîne de caractères #2     */
-
-
-    int integer;
-
-    conv_func *subst;                       /* Fonction de conversion      */
-    arg_list_t *args;                       /* Liste d'arguments           */
-
-    arg_expr_t *arg;                        /* Argument multi-usages       */
-    ConvUnaryOperation un_op;               /* Opération unaire            */
-    ConvBinaryOperation bin_op;             /* Opération bianire           */
-
-
-    cond_expr *expr;                        /* Expression de déclenchement */
-    rule_action raction;                    /* Action et éléments associés */
-
-}
-
-%parse-param { rented_coder *coder }
-
-
-%token COPYRIGHT
-%token TITLE
-%token INS_NAME INS_DETAILS
-
-%token ENCODING
-%token TYPE NUMBER
-%token ENC_START ENC_END
-
-%token WORD HALF NAME SIZE BIT
-
-%token SYNTAX OPERAND_NAME OPERAND_INTERNAL OPERAND_VISIBLE
-
-%token CONV EQ OP COMMA CP NOT AND_LOG EOR COLON
-
-%token HOOKS
-
-%token RULES IF EXPR_START EQUAL BINVAL HEXVAL EXPR_END AND THEN SEE CALL CHK_CALL UNPREDICTABLE
-
-
-%type <string> COPYRIGHT INS_NAME
-%type <cstring> INS_DETAILS
-
-%type <string> TYPE
-%type <integer> NUMBER
-
-%type <string> NAME
-%type <integer> SIZE BIT
-
-%type <string> OPERAND_NAME OPERAND_INTERNAL OPERAND_VISIBLE
-
-%type <subst> substitution
-
-%type <args> arg_list
-%type <arg> arg_expr arg_composed
-%type <un_op> arg_expr_un_op
-%type <bin_op> arg_expr_bin_op
-%type <string> arg_field
-
-%type <expr> rule_cond
-%type <string> BINVAL HEXVAL
-%type <raction> action
-
-
-%%
-
-
-input : name encodings { if (!dump_all_routines_using_coder(coder)) YYABORT; }
-
-name : COPYRIGHT TITLE INS_NAME             { save_notes_for_coder(coder, $1, $3, NULL); }
-     | COPYRIGHT TITLE INS_NAME INS_DETAILS { save_notes_for_coder(coder, $1, $3, $4); }
-
-
-
-
-encodings : /* empty */
-          | encoding encodings
-
-encoding : ENCODING TYPE NUMBER content { push_encoding_spec(coder, $2, $3); }
-
-
-content : /* empty */
-        | bitfield content
-        | syntax content
-        | conversions content
-        | hooks content
-        | rules content
-
-
-bitfield : HALF bits {
-                       if (count_coder_bits(coder) != 16)
-                       {
-                         fprintf(stderr, "Unexpected word size: %u vs 16\n", count_coder_bits(coder));
-                         YYABORT;
-                       }
-                     }
-         | WORD bits {
-                       if (count_coder_bits(coder) != 32)
-                       {
-                         fprintf(stderr, "Unexpected word size: %u vs 32\n", count_coder_bits(coder));
-                         YYABORT;
-                       }
-                     }
-
-bits : /* empty */
-     | NAME SIZE bits   { register_named_field_in_coder(coder, $1, $2); }
-     | BIT bits         { register_bit_in_coder(coder, $1); }
-
-
-syntax : SYNTAX operands
-
-operands : /* empty */
-         | operands OPERAND_NAME     { register_syntax_item_in_coder(coder, $2, SIT_KEYWORD); }
-         | operands OPERAND_INTERNAL { register_syntax_item_in_coder(coder, $2, SIT_INT_OPERAND); }
-         | operands OPERAND_VISIBLE  { register_syntax_item_in_coder(coder, $2, SIT_EXT_OPERAND); }
-
-
-conversions : CONV substitutions
-
-substitutions : /* empty */
-              | substitutions substitution { register_conversion_in_coder(coder, $2); }
-
-substitution : NAME EQ arg_expr            { $$ = make_conv_from_expr($1, $3); }
-             | NAME EQ NAME OP arg_list CP { $$ = make_conv_from_func($1, $3, $5); }
-
-
-arg_list : arg_expr                { $$ = build_arg_list($1); }
-         | arg_list COMMA arg_expr { $$ = extend_arg_list($1, $3); }
-
-arg_expr : NAME                                     { $$ = build_arg_expr_from_name($1); }
-          | NUMBER                                  { $$ = build_arg_expr_from_number($1); }
-          | BINVAL                                  { $$ = build_arg_expr_from_binval($1); }
-          | HEXVAL                                  { $$ = build_arg_expr_from_hexval($1); }
-          | arg_composed                            { $$ = $1; }
-          | OP arg_expr CP                          { $$ = $2; }
-          | arg_expr_un_op arg_expr                 { $$ = build_unary_arg_expr($2, $1); }
-          | arg_expr arg_expr_bin_op arg_expr       { $$ = build_binary_arg_expr($1, $3, $2); }
-
-arg_expr_un_op : NOT { $$ = CUO_NOT; }
-
-arg_expr_bin_op : AND_LOG { $$ = CBO_AND; }
-                | EOR { $$ = CBO_EOR; }
-
-arg_composed : arg_field COLON arg_field    { $$ = build_composed_arg_expr($1, $3); }
-             | arg_composed COLON arg_field { $$ = extend_composed_arg_expr($1, $3); }
-
-arg_field : NAME   { $$ = $1; }
-          | BINVAL { $$ = $1; }
-
-
-hooks : HOOKS hookings
-
-hookings : /* empty */
-         | hookings hooking
-
-hooking : NAME EQ NAME { register_hook_in_coder(coder, $1, $3); }
-
-
-rules : RULES rules_list
-
-rules_list : /* empty */
-           | rules_list rule
-
-rule : IF EXPR_START rule_cond EXPR_END THEN action { add_conditional_rule_to_coder(coder, $3, &$6); }
-     | action                                       { add_conditional_rule_to_coder(coder, NULL, &$1); }
-
-rule_cond : NAME EQUAL BINVAL   { $$ = build_simple_cond_expression($1, CCT_EQUAL, $3, true); }
-          | NAME EQUAL HEXVAL   { $$ = build_simple_cond_expression($1, CCT_EQUAL, $3, false); }
-          | NAME AND_LOG BINVAL { $$ = build_simple_cond_expression($1, CCT_AND, $3, true); }
-          | NAME AND_LOG HEXVAL { $$ = build_simple_cond_expression($1, CCT_AND, $3, false); }
-          | EXPR_START rule_cond EXPR_END AND EXPR_START rule_cond EXPR_END
-                                { $$ = build_composed_cond_expression($2, COT_AND, $6); }
-
-action : SEE INS_DETAILS              { $$.type = CAT_SEE; $$.details = make_callable($2, false); }
-       | UNPREDICTABLE                { $$.type = CAT_UNPREDICTABLE; }
-       | CALL NAME OP arg_list CP     { $$.type = CAT_CALL; $$.callee = $2; $$.args = $4; }
-       | CHK_CALL NAME OP arg_list CP { $$.type = CAT_CHECKED_CALL; $$.callee = $2; $$.args = $4; }
-
-
-%%
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : coder = codeur impliqué dans le processus.                   *
-*                msg   = message d'erreur.                                    *
-*                                                                             *
-*  Description : Affiche un message d'erreur suite à l'analyse en échec.      *
-*                                                                             *
-*  Retour      : 0                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static int d2c_error(rented_coder *coder, char *msg)
-{
-	printf("yyerror line %d: %s\n", d2c_get_lineno(), msg);
-
-	return 0;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : argv0 = nombre du programme exécuté.                         *
-*                                                                             *
-*  Description : Affiche des indications sur l'utilisation du programme.      *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void show_usage(const char *argv0)
-{
-    printf("\n");
-
-    printf("Usage: %s [options] < file\n", argv0);
-
-    printf("\n");
-
-    printf("Options:\n");
-
-    printf("\n");
-
-    printf("\t-h | --help\t\t\tDisplay this messsage.\n");
-    printf("\t-d | --dir <string>\t\tSpecify the main output directory.\n");
-    printf("\t-a | --arch <string>\t\tDefine the archicture to handle.\n");
-    printf("\t-H | --header <string>\t\tSet the base of the #ifndef / #define game.\n");
-    printf("\t-e | --encoding <string>\tDefine encoding prefixes for files.\n");
-    printf("\t-m | --macro <string>\t\tRegister some conversion functions.\n");
-
-    printf("\n");
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : argc = nombre d'arguments dans la ligne de commande.         *
-*                argv = arguments de la ligne de commande.                    *
-*                                                                             *
-*  Description : Point d'entrée du programme.                                 *
-*                                                                             *
-*  Retour      : EXIT_SUCCESS si le prgm s'est déroulé sans encombres.        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-int main(int argc, char **argv)
-{
-    int result;                             /* Bilan à retourner           */
-    rented_coder *coder;                    /* Codeur à briffer & employer */           
-    int index;                              /* Indice de fichier à traiter */
-    bool need_help;                         /* Affichage de l'aide ?       */
-    bool has_error;                         /* Erreur dans la ligne de cmd.*/
-    int ret;                                /* Bilan d'une lecture d'arg.  */
-    char *sep;                              /* Caratère '=' en coupure     */
-
-    static struct option long_options[] = {
-
-        { "help",       no_argument,        NULL,   'h' },
-        { "input",      required_argument,  NULL,   'i' },
-        { "dir",        required_argument,  NULL,   'd' },
-        { "arch",       required_argument,  NULL,   'a' },
-        { "header",     required_argument,  NULL,   'H' },
-        { "encoding",   required_argument,  NULL,   'e' },
-        { "macro",      required_argument,  NULL,   'M' },
-        { NULL,         0,                  NULL,   0   }
-
-    };
-
-    result = EXIT_SUCCESS;
-
-    coder = create_coder();
-
-    index = 0;
-
-    need_help = false;
-    has_error = false;
-
-    while (!has_error)
-    {
-        ret = getopt_long(argc, argv, "hi:d:a:H:e:M:", long_options, &index);
-        if (ret == -1) break;
-
-        switch (ret)
-        {
-            case 'h':
-                need_help = true;
-                break;
-
-            case 'i':
-                set_coder_input_file(coder, optarg);
-                break;
-
-            case 'd':
-                set_coder_output_directory(coder, optarg);
-                break;
-
-            case 'a':
-                set_coder_arch(coder, optarg);
-                break;
-
-            case 'H':
-                set_coder_header_base(coder, optarg);
-                break;
-
-            case 'e':
-
-                sep = strchr(optarg, '=');
-                has_error = (sep == NULL);
-
-                if (!has_error)
-                {
-                    *sep = '\0';
-                    register_encoding(get_coder_pre_proc(coder), optarg, sep + 1);
-                }
-
-                break;
-
-            case 'M':
-
-                sep = strchr(optarg, '=');
-                has_error = (sep == NULL);
-
-                if (!has_error)
-                {
-                    *sep = '\0';
-                    define_macro(get_coder_pre_proc(coder), optarg, sep + 1);
-                }
-
-                break;
-
-        }
-
-    }
-
-    if (need_help || has_error || !do_basic_checks_with_coder(coder) || optind != argc)
-    {
-        show_usage(argv[0]);
-        result = (need_help ? EXIT_SUCCESS : EXIT_FAILURE);
-        goto exit;
-    }
-
-	result = yyparse(coder);
-
- exit:
-
-    free_flex_memory();
-
-    delete_coder(coder);
-
-    return result;
-
-}
diff --git a/tools/d2c/d2c_tok.l b/tools/d2c/d2c_tok.l
deleted file mode 100644
index 300508d..0000000
--- a/tools/d2c/d2c_tok.l
+++ /dev/null
@@ -1,235 +0,0 @@
-
-%{
-
-typedef struct _rented_coder rented_coder;
-
-
-#include "d2c-d2c_gram.h"
-
-#include <ctype.h>
-#include <string.h>
-
-
-/* Tente de libérer autant de mémoire que possible...  */
-void free_flex_memory(void) ;
-
-
-%}
-
-%option noyywrap
-%option nounput
-%option noinput
-%option yylineno
-%option stack
-%option noyy_top_state
-
-
-%x comments
-
-%x ins_name try_details ins_details
-%x encoding encoding_type encoding_content
-
-%x encoding_bits encoding_bits_size
-
-%x syntax syntax_name syntax_int syntax_ext
-
-%x conv_begin conv_content
-
-%x arg arg_binval arg_hexval
-
-%x hooks_begin hooks_content
-
-%x rules_begin rules_content rules_cond rules_cond_binval rules_cond_hexval rules_action rules_action_see rules_action_call
-
-
-%%
-
-
-[ \t\n]+                            { }
-
-"/*"                                { BEGIN(comments); }
-<comments>"*/"                      { BEGIN(INITIAL); }
-<comments>[^*\n]                    { }
-<comments>"Copyright"[^\n]*         { d2c_lval.string = strdup(yytext); return COPYRIGHT; }
-<comments>"*"                       { }
-<comments>"\n"                      { }
-
-
-"@title"                            { BEGIN(ins_name); return TITLE; }
-
-<ins_name>[ ][A-Za-z-]+             { d2c_lval.string = strdup(yytext + 1); BEGIN(try_details); return INS_NAME; }
-<try_details>[ ,/]                  { BEGIN(ins_details); }
-<try_details>[\n]                   { BEGIN(INITIAL); }
-
-<ins_details>[^\n]*                 { d2c_lval.cstring = yytext; return INS_DETAILS; }
-<ins_details>[\n]                   { BEGIN(INITIAL); }
-
-
-
-"@encoding"                         { BEGIN(encoding); return ENCODING; }
-
-<encoding>[ ]                       { }
-<encoding>"("                       { BEGIN(encoding_type); }
-
-<encoding_type>[A-Za-z]             { d2c_lval.string = strdup(yytext); return TYPE; }
-<encoding_type>[0-9]+               { d2c_lval.integer = atoi(yytext); return NUMBER; }
-<encoding_type>")"                  { BEGIN(encoding); }
-
-<encoding>"{"                       { BEGIN(encoding_content); }
-<encoding_content>[ \t\n]+          { }
-<encoding_content>"}"               { BEGIN(INITIAL); }
-
-
-
-<encoding_content>"@half"           { BEGIN(encoding_bits); return HALF; }
-<encoding_content>"@word"           { BEGIN(encoding_bits); return WORD; }
-
-<encoding_bits>" "                     { }
-<encoding_bits>"\n"                    { BEGIN(encoding_content); }
-<encoding_bits>[A-Za-z_][A-Za-z0-9__]* { d2c_lval.string = strdup(yytext); return NAME; }
-
-<encoding_bits>"("                  { BEGIN(encoding_bits_size); }
-<encoding_bits_size>[0-9]+          { d2c_lval.integer = atoi(yytext); return SIZE; }
-<encoding_bits_size>")"             { BEGIN(encoding_bits); }
-
-<encoding_bits>[01]                 { d2c_lval.integer = atoi(yytext); return BIT; }
-
-
-
-<encoding_content>"@syntax"         { BEGIN(syntax); return SYNTAX; }
-
-<syntax>[ ]+                        { }
-<syntax>"\n"                        { BEGIN(encoding_content); }
-
-<syntax>[\"]                        { BEGIN(syntax_name); }
-<syntax_name>[^ \n\"]+              { d2c_lval.string = strdup(yytext); return OPERAND_NAME; }
-<syntax_name>[\"]                   { BEGIN(syntax); }
-
-<syntax>"{"                         { BEGIN(syntax_int); }
-<syntax_int>[^ \n}]+                { d2c_lval.string = strdup(yytext); return OPERAND_INTERNAL; }
-<syntax_int>"}"                     { BEGIN(syntax); }
-
-<syntax>"<"                         { BEGIN(syntax_ext); }
-<syntax_ext>[^ \n>]+                { d2c_lval.string = strdup(yytext); return OPERAND_VISIBLE; }
-<syntax_ext>">"                     { BEGIN(syntax); }
-
-
-
-<encoding_content>"@conv"           { BEGIN(conv_begin); return CONV; }
-<conv_begin>[ ]+                    { }
-<conv_begin>"{"                     { BEGIN(conv_content); }
-<conv_content>"}"                   { BEGIN(encoding_content); }
-
-<conv_content>[ \t\n]+              { }
-<conv_content>[A-Za-z_][A-Za-z0-9_]* {
-                                      if (strcmp(yytext, "NOT") == 0) return NOT;
-                                      else
-                                      {
-                                          d2c_lval.string = strdup(yytext);
-                                          return NAME;
-                                      }
-                                    }
-<conv_content>"="                   { return EQ; }
-<conv_content>"("                   { yy_push_state(arg); return OP; }
-
-
-
-
-<arg>[A-Za-z_][A-Za-z0-9_]*    {
-                                      if (strcmp(yytext, "NOT") == 0) return NOT;
-                                      else if (strcmp(yytext, "AND") == 0) return AND_LOG;
-                                      else if (strcmp(yytext, "EOR") == 0) return EOR;
-                                      else
-                                      {
-                                          d2c_lval.string = strdup(yytext);
-                                          return NAME;
-                                      }
-                                    }
-<arg>[0-9][0-9]*               { d2c_lval.integer = atoi(yytext); return NUMBER; }
-<arg>"'"                       { BEGIN(arg_binval); }
-<arg_binval>[01][01]*          { d2c_lval.string = strdup(yytext); return BINVAL; }
-<arg_binval>"'"                { BEGIN(arg); }
-<arg>"0x"                      { BEGIN(arg_hexval); }
-<arg_hexval>[0-9a-f][0-9a-f]*  { d2c_lval.string = strdup(yytext); BEGIN(arg); return HEXVAL; }
-<arg>","                       { return COMMA; }
-<arg>":"                       { return COLON; }
-<arg>"&"                       { return AND_LOG; }
-<arg>[ ]+                      { }
-<arg>"("                       { yy_push_state(arg); return OP; }
-<arg>")"                       { yy_pop_state(); return CP; }
-
-
-
-<encoding_content>"@hooks"          { BEGIN(hooks_begin); return HOOKS; }
-<hooks_begin>[ ]+                   { }
-<hooks_begin>"{"                    { BEGIN(hooks_content); }
-<hooks_content>"}"                  { BEGIN(encoding_content); }
-
-<hooks_content>[ \t\n]+             { }
-<hooks_content>[a-z_][a-z0-9_]*     { d2c_lval.string = strdup(yytext); return NAME; }
-<hooks_content>"="                  { return EQ; }
-
-
-
-<encoding_content>"@rules"          { BEGIN(rules_begin); return RULES; }
-<rules_content>\/\/[^\n]+           { printf("SKIP '%s'\n", yytext); }
-<rules_begin>[ ]+                   { }
-<rules_begin>"{"                    { BEGIN(rules_content); }
-<rules_content>[ \t\n]+             { }
-<rules_content>"}"                  { BEGIN(encoding_content); }
-
-<rules_content>"see "               { BEGIN(rules_action_see); return SEE; }
-<rules_content>"unpredictable"      { return UNPREDICTABLE; }
-<rules_content>"call"               { BEGIN(rules_action_call); return CALL; }
-<rules_content>"chk_call"           { BEGIN(rules_action_call); return CHK_CALL; }
-
-<rules_content>"if"                 { BEGIN(rules_cond); return IF; }
-<rules_cond>[ ]+                    { }
-<rules_cond>"("                     { return EXPR_START; }
-<rules_cond>[A-Za-z_][A-Za-z0-9_]*  { d2c_lval.string = strdup(yytext); return NAME; }
-<rules_cond>"=="                    { return EQUAL; }
-<rules_cond>"'"                     { BEGIN(rules_cond_binval); }
-<rules_cond_binval>[01][01]*        { d2c_lval.string = strdup(yytext); return BINVAL; }
-<rules_cond_binval>"'"              { BEGIN(rules_cond); }
-<rules_cond>"0x"                     { BEGIN(rules_cond_hexval); }
-<rules_cond_hexval>[0-9a-f][0-9a-f]* { d2c_lval.string = strdup(yytext); BEGIN(rules_cond); return HEXVAL; }
-<rules_cond>")"                     { return EXPR_END; }
-<rules_cond>"&&"                    { return AND; }
-<rules_cond>"&"                    { return AND_LOG; }
-
-<rules_cond>";"                     { BEGIN(rules_action); return THEN; }
-<rules_action>[ ]+                  { }
-
-<rules_action>"see "                { BEGIN(rules_action_see); return SEE; }
-<rules_action_see>[^\n]*            { d2c_lval.cstring = yytext; BEGIN(rules_content); return INS_DETAILS; }
-
-<rules_action>"unpredictable"       { BEGIN(rules_content); return UNPREDICTABLE; }
-
-<rules_action>"call"                      { BEGIN(rules_action_call); return CALL; }
-<rules_action>"chk_call"                  { BEGIN(rules_action_call); return CHK_CALL; }
-<rules_action_call>[\t ]+                 { }
-<rules_action_call>[A-Za-z_][A-Za-z0-9_]* { d2c_lval.string = strdup(yytext); return NAME; }
-<rules_action_call>"("                    { yy_push_state(arg); return OP; }
-<rules_action_call>[\n]                   { BEGIN(rules_content); }
-
-
-%%
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : -                                                            *
-*                                                                             *
-*  Description : Tente de libérer autant de mémoire que possible...           *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void free_flex_memory(void)
-{
-    yy_delete_buffer(YY_CURRENT_BUFFER);
-
-}
diff --git a/tools/d2c/grammar.y b/tools/d2c/grammar.y
new file mode 100644
index 0000000..986edd7
--- /dev/null
+++ b/tools/d2c/grammar.y
@@ -0,0 +1,443 @@
+
+%{
+
+#include <getopt.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include "tokens.h"
+
+
+/* Affiche un message d'erreur suite à l'analyse en échec. */
+static int d2c_error(rented_coder *, char *, char *);
+
+/* Affiche des indications sur l'utilisation du programme. */
+static void show_usage(const char *);
+
+/* Prépare le traitement d'un contenu en l'affichant en mémoire. */
+static void *map_input_data(const char *, size_t *);
+
+%}
+
+
+%code requires {
+
+#include "coder.h"
+#include "helpers.h"
+#include "args/decl.h"
+#include "bits/decl.h"
+#include "conv/decl.h"
+#include "hooks/decl.h"
+#include "rules/decl.h"
+#include "syntax/decl.h"
+
+
+#define handle_coder_bits(c, e, r)                          \
+    ({                                                      \
+        encoding_spec *__spec;                              \
+        coding_bits *__bits;                                \
+        bool __status;                                      \
+        __spec = get_current_encoding_spec(c);              \
+        __bits = get_bits_in_encoding_spec(__spec);         \
+        __status = load_bits_from_raw_line(__bits, e, r);   \
+        if (!__status) YYABORT;                             \
+    })
+
+#define handle_coder_syntax(c, r)                           \
+    ({                                                      \
+        encoding_spec *__spec;                              \
+        asm_syntax *__syntax;                               \
+        bool __status;                                      \
+        __spec = get_current_encoding_spec(c);              \
+        __syntax = get_syntax_in_encoding_spec(__spec);     \
+        __status = load_syntax_from_raw_line(__syntax, r);  \
+        if (!__status) YYABORT;                             \
+    })
+
+#define handle_coder_conversions(c, r)                      \
+    ({                                                      \
+        encoding_spec *__spec;                              \
+        conv_list *__list;                                  \
+        bool __status;                                      \
+        __spec = get_current_encoding_spec(c);              \
+        __list = get_conversions_in_encoding_spec(__spec);  \
+        __status = load_convs_from_raw_block(__list, r);    \
+        if (!__status) YYABORT;                             \
+    })
+
+#define handle_coder_hooks(c, r)                            \
+    ({                                                      \
+        encoding_spec *__spec;                              \
+        instr_hooks *__hooks;;                              \
+        bool __status;                                      \
+        __spec = get_current_encoding_spec(c);              \
+        __hooks = get_hooks_in_encoding_spec(__spec);       \
+        __status = load_hooks_from_raw_line(__hooks, r);    \
+        if (!__status) YYABORT;                             \
+    })
+
+#define handle_coder_rules(c, r)                            \
+    ({                                                      \
+        encoding_spec *__spec;                              \
+        decoding_rules *__rules;                            \
+        bool __status;                                      \
+        __spec = get_current_encoding_spec(c);              \
+        __rules = get_rules_in_encoding_spec(__spec);       \
+        __status = load_rules_from_raw_block(__rules, r);   \
+        if (!__status) YYABORT;                             \
+    })
+
+}
+
+%union {
+
+    char *string;                           /* Chaîne de caractères #1     */
+    const char *cstring;                    /* Chaîne de caractères #2     */
+
+    int integer;                            /* Valeur entière              */
+
+}
+
+
+/**
+ * Cf.
+ * http://stackoverflow.com/questions/34418381/how-to-reference-lex-or-parse-parameters-in-flex-rules/34420950
+ */
+
+%define api.pure full
+
+%parse-param { rented_coder *coder } { char *temp }
+%lex-param { char *temp }
+
+%code provides {
+
+#define YY_DECL \
+    int d2c_lex(YYSTYPE *yylvalp, char *temp)
+
+YY_DECL;
+
+}
+
+
+%token COPYRIGHT
+%token TITLE
+%token INS_NAME INS_DETAILS
+
+%token ENCODING
+%token TYPE NUMBER
+%token ENC_START ENC_END
+
+%token WORD HALF
+%token SYNTAX
+%token CONV
+%token HOOKS
+%token RULES
+
+%token RAW_LINE RAW_BLOCK
+
+
+%type <string> COPYRIGHT INS_NAME
+%type <cstring> INS_DETAILS
+
+%type <string> TYPE
+%type <integer> NUMBER
+
+%type <cstring> RAW_LINE RAW_BLOCK
+
+
+%%
+
+
+input : name encodings { if (!dump_all_routines_using_coder(coder)) YYABORT; }
+
+name : COPYRIGHT TITLE INS_NAME             { save_notes_for_coder(coder, $1, $3, NULL); }
+     | COPYRIGHT TITLE INS_NAME INS_DETAILS { save_notes_for_coder(coder, $1, $3, $4); }
+
+
+encodings : /* empty */
+          | encoding encodings
+
+encoding : ENCODING TYPE NUMBER content { push_encoding_spec(coder, $2, $3); }
+
+
+content : /* empty */
+        | bitfield content
+        | syntax content
+        | conversions content
+        | hooks content
+        | rules content
+
+
+bitfield : HALF RAW_LINE { handle_coder_bits(coder, 16, $2); }
+         | WORD RAW_LINE { handle_coder_bits(coder, 32, $2); }
+
+syntax : SYNTAX RAW_LINE { handle_coder_syntax(coder, $2); }
+
+conversions : CONV RAW_BLOCK { handle_coder_conversions(coder, $2); }
+
+hooks : HOOKS RAW_BLOCK { handle_coder_hooks(coder, $2); }
+
+rules : RULES RAW_BLOCK { handle_coder_rules(coder, $2); }
+
+
+%%
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : coder = codeur impliqué dans le processus.                   *
+*                temp  = zone de travail à destination des lectures manuelles.*
+*                msg   = message d'erreur.                                    *
+*                                                                             *
+*  Description : Affiche un message d'erreur suite à l'analyse en échec.      *
+*                                                                             *
+*  Retour      : 0                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int d2c_error(rented_coder *coder, char *temp, char *msg)
+{
+	printf("yyerror line %d: %s\n", d2c_get_lineno(), msg);
+
+	return 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : argv0 = nombre du programme exécuté.                         *
+*                                                                             *
+*  Description : Affiche des indications sur l'utilisation du programme.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void show_usage(const char *argv0)
+{
+    printf("\n");
+
+    printf("Usage: %s [options] < file\n", argv0);
+
+    printf("\n");
+
+    printf("Options:\n");
+
+    printf("\n");
+
+    printf("\t-h | --help\t\t\tDisplay this messsage.\n");
+    printf("\t-d | --dir <string>\t\tSpecify the main output directory.\n");
+    printf("\t-a | --arch <string>\t\tDefine the archicture to handle.\n");
+    printf("\t-H | --header <string>\t\tSet the base of the #ifndef / #define game.\n");
+    printf("\t-e | --encoding <string>\tDefine encoding prefixes for files.\n");
+    printf("\t-m | --macro <string>\t\tRegister some conversion functions.\n");
+
+    printf("\n");
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : filename = chemin du fichier à charger en mémoire.           *
+*                length   = taille de l'espace mémoie à mettre en place. [OUT]*
+*                                                                             *
+*  Description : Prépare le traitement d'un contenu en l'affichant en mémoire.*
+*                                                                             *
+*  Retour      : Adresse valide ou MAP_FAILED en cas d'échec.                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void *map_input_data(const char *filename, size_t *length)
+{
+    void *result;                           /* Espace mémoire à retourner  */
+    int fd;                                 /* Descripteur du fichier      */
+    struct stat info;                       /* Informations sur le fichier */
+    int ret;                                /* Bilan d'un appel            */
+
+    result = NULL;
+
+    fd = open(filename, O_RDONLY);
+    if (fd == -1)
+    {
+        perror("open");
+        goto mid_exit;
+    }
+
+    ret = fstat(fd, &info);
+    if (ret == -1)
+    {
+        perror("fstat");
+        goto mid_exit_with_fd;
+    }
+
+    *length = info.st_size;
+
+    result = mmap(NULL, *length, PROT_READ, MAP_PRIVATE, fd, 0);
+    if (result == MAP_FAILED)
+    {
+        perror("mmap");
+        goto mid_exit_with_fd;
+    }
+
+ mid_exit_with_fd:
+
+    close(fd);
+
+ mid_exit:
+
+    return result;
+
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : argc = nombre d'arguments dans la ligne de commande.         *
+*                argv = arguments de la ligne de commande.                    *
+*                                                                             *
+*  Description : Point d'entrée du programme.                                 *
+*                                                                             *
+*  Retour      : EXIT_SUCCESS si le prgm s'est déroulé sans encombres.        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int main(int argc, char **argv)
+{
+    int result;                             /* Bilan à retourner           */
+    rented_coder *coder;                    /* Codeur à briffer & employer */           
+    int index;                              /* Indice de fichier à traiter */
+    bool need_help;                         /* Affichage de l'aide ?       */
+    bool has_error;                         /* Erreur dans la ligne de cmd.*/
+    int ret;                                /* Bilan d'une lecture d'arg.  */
+    char *sep;                              /* Caratère '=' en coupure     */
+    size_t length;                          /* Nombre d'octets à traiter   */
+    char *content;                          /* Contenu brut à analyser     */
+    char *temp;                             /* Zone de travail temporaire  */
+    YY_BUFFER_STATE state;                  /* Contexte d'analyse          */
+
+    static struct option long_options[] = {
+
+        { "help",       no_argument,        NULL,   'h' },
+        { "input",      required_argument,  NULL,   'i' },
+        { "dir",        required_argument,  NULL,   'd' },
+        { "arch",       required_argument,  NULL,   'a' },
+        { "header",     required_argument,  NULL,   'H' },
+        { "encoding",   required_argument,  NULL,   'e' },
+        { "macro",      required_argument,  NULL,   'M' },
+        { NULL,         0,                  NULL,   0   }
+
+    };
+
+    result = EXIT_SUCCESS;
+
+    coder = create_coder();
+
+    index = 0;
+
+    need_help = false;
+    has_error = false;
+
+    while (!has_error)
+    {
+        ret = getopt_long(argc, argv, "hi:d:a:H:e:M:", long_options, &index);
+        if (ret == -1) break;
+
+        switch (ret)
+        {
+            case 'h':
+                need_help = true;
+                break;
+
+            case 'i':
+                set_coder_input_file(coder, optarg);
+                break;
+
+            case 'd':
+                set_coder_output_directory(coder, optarg);
+                break;
+
+            case 'a':
+                set_coder_arch(coder, optarg);
+                break;
+
+            case 'H':
+                set_coder_header_base(coder, optarg);
+                break;
+
+            case 'e':
+
+                sep = strchr(optarg, '=');
+                has_error = (sep == NULL);
+
+                if (!has_error)
+                {
+                    *sep = '\0';
+                    register_encoding(get_coder_pre_proc(coder), optarg, sep + 1);
+                }
+
+                break;
+
+            case 'M':
+
+                sep = strchr(optarg, '=');
+                has_error = (sep == NULL);
+
+                if (!has_error)
+                {
+                    *sep = '\0';
+                    define_macro(get_coder_pre_proc(coder), optarg, sep + 1);
+                }
+
+                break;
+
+        }
+
+    }
+
+    if (need_help || has_error || !do_basic_checks_with_coder(coder) || optind != argc)
+    {
+        show_usage(argv[0]);
+        result = (need_help ? EXIT_SUCCESS : EXIT_FAILURE);
+        goto exit;
+    }
+
+    content = map_input_data(get_coder_input_file(coder), &length);
+    if (content == MAP_FAILED)
+    {
+        result = EXIT_FAILURE;
+        goto exit;
+    }
+
+    temp = (char *)calloc(length, sizeof(char));
+
+    state = d2c__scan_bytes(content, length);
+
+    result = yyparse(coder, temp);
+
+    yy_delete_buffer(state);
+
+    free(temp);
+
+    munmap(content, length);
+
+ exit:
+
+    delete_coder(coder);
+
+    return result;
+
+}
diff --git a/tools/d2c/helpers.h b/tools/d2c/helpers.h
index 8c39a85..1df821c 100644
--- a/tools/d2c/helpers.h
+++ b/tools/d2c/helpers.h
@@ -21,8 +21,8 @@
  */
 
 
-#ifndef _TOOLS_HELPERS_H
-#define _TOOLS_HELPERS_H
+#ifndef _TOOLS_D2C_HELPERS_H
+#define _TOOLS_D2C_HELPERS_H
 
 
 #include <ctype.h>
@@ -44,4 +44,4 @@ char *make_callable(const char *raw, bool);
 
 
 
-#endif  /* _TOOLS_HELPERS_H */
+#endif  /* _TOOLS_D2C_HELPERS_H */
diff --git a/tools/d2c/hooks.c b/tools/d2c/hooks.c
deleted file mode 100644
index a110664..0000000
--- a/tools/d2c/hooks.c
+++ /dev/null
@@ -1,169 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * syntax.c - prise en compte d'une syntaxe du langage d'assemblage
- *
- * Copyright (C) 2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  OpenIDA is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  OpenIDA is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "hooks.h"
-
-
-#include <malloc.h>
-#include <string.h>
-
-
-#include "helpers.h"
-
-
-
-/* Paramèter d'une fonction de renvoi */
-typedef struct _instr_func
-{
-    char *type;                             /* Type de fonction définie    */
-    char *name;                             /* Désignation humaine         */
-
-} instr_func;
-
-/* Liste des fonctions de renvoi pour une instruction */
-struct _instr_hooks
-{
-    instr_func *funcs;                      /* Liste de fonctions présentes*/
-    size_t func_count;                      /* Taille de cette liste       */
-
-};
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : -                                                            *
-*                                                                             *
-*  Description : Crée une liste de fonctions à lier à une instruction.        *
-*                                                                             *
-*  Retour      : Nouvelle structure prête à emploi.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-instr_hooks *create_instr_hooks(void)
-{
-    instr_hooks *result;                    /* Définition vierge à renvoyer*/
-
-    result = (instr_hooks *)calloc(1, sizeof(instr_hooks));
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : hooks = gestionnaire d'un ensemble de fonctions associées.   *
-*                                                                             *
-*  Description : Supprime de la mémoire une liste de fonctions liées.         *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void delete_instr_hooks(instr_hooks *hooks)
-{
-    size_t i;                               /* Boucle de parcours          */
-
-    for (i = 0; i < hooks->func_count; i++)
-    {
-        free(hooks->funcs[i].type);
-        free(hooks->funcs[i].name);
-    }
-
-    if (hooks->funcs != NULL)
-        free(hooks->funcs);
-
-    free(hooks);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : hooks = gestionnaire d'un ensemble de fonctions associées.   *
-*                type  = type de fonction à enregistrer pour une instruction. *
-*                name  = désignation de la fonction à associer.               *
-*                                                                             *
-*  Description : Enregistre l'utilité d'une fonction pour une instruction.    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void register_hook_function(instr_hooks *hooks, char *type, char *name)
-{
-    instr_func *func;                       /* Nouvelle prise en compte    */
-
-    hooks->funcs = (instr_func *)realloc(hooks->funcs, ++hooks->func_count * sizeof(instr_func));
-
-    func = &hooks->funcs[hooks->func_count - 1];
-
-    func->type = make_string_upper(type);
-    func->name = strdup(name);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : hooks = gestionnaire d'un ensemble de fonctions associées.   *
-*                fd    = descripteur d'un flux ouvert en écriture.            *
-*                                                                             *
-*  Description : Associe dans le code des fonctions à une instruction.        *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool write_hook_functions(const instr_hooks *hooks, int fd)
-{
-    bool result;                            /* Bilan à retourner           */
-    size_t i;                               /* Boucle de parcours          */
-    instr_func *func;                       /* Nouvelle prise en compte    */
-
-    result = true;
-
-    for (i = 0; i < hooks->func_count && result; i++)
-    {
-        func = &hooks->funcs[i];
-
-        dprintf(fd, "\t\tg_arch_instruction_set_hook(instr, IPH_%s, (instr_hook_fc)%s);\n",
-                func->type, func->name);
-
-    }
-
-    if (hooks->func_count > 0 && result)
-        dprintf(fd, "\n");
-
-    return result;
-
-}
diff --git a/tools/d2c/hooks.h b/tools/d2c/hooks.h
deleted file mode 100644
index 5dbf223..0000000
--- a/tools/d2c/hooks.h
+++ /dev/null
@@ -1,51 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * hooks.h - prototypes pour la prise en compte d'une hookse du langage d'assemblage
- *
- * Copyright (C) 2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  OpenIDA is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  OpenIDA is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _TOOLS_HOOKS_H
-#define _TOOLS_HOOKS_H
-
-
-#include <stdbool.h>
-
-
-
-/* Liste des fonctions de renvoi pour une instruction */
-typedef struct _instr_hooks instr_hooks;
-
-
-
-/* Crée une liste de fonctions à lier à une instruction. */
-instr_hooks *create_instr_hooks(void);
-
-/* Supprime de la mémoire une liste de fonctions liées. */
-void delete_instr_hooks(instr_hooks *);
-
-/* Enregistre l'utilité d'une fonction pour une instruction. */
-void register_hook_function(instr_hooks *, char *, char *);
-
-/* Associe dans le code des fonctions à une instruction. */
-bool write_hook_functions(const instr_hooks *, int);
-
-
-
-#endif  /* _TOOLS_HOOKS_H */
diff --git a/tools/d2c/hooks/Makefile.am b/tools/d2c/hooks/Makefile.am
new file mode 100644
index 0000000..1eb00a8
--- /dev/null
+++ b/tools/d2c/hooks/Makefile.am
@@ -0,0 +1,31 @@
+
+BUILT_SOURCES = grammar.h
+
+
+# On évite d'utiliser les variables personnalisées de type *_la_[YL]FLAGS
+# afin de conserver des noms de fichiers simples, ie sans le nom de la
+# bibliothèque de sortie en préfixe.
+
+AM_YFLAGS = -v -d -p hooks_
+
+AM_LFLAGS = -P hooks_ -o lex.yy.c --header-file=tokens.h			\
+			-Dyylval=hooks_lval -Dyyget_lineno=hooks_get_lineno 	\
+			-Dyy_scan_string=hooks__scan_string					\
+			-Dyy_delete_buffer=hooks__delete_buffer
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS)
+
+
+noinst_LTLIBRARIES  = libd2chooks.la
+
+.NOTPARALLEL: $(noinst_LTLIBRARIES)
+
+libd2chooks_la_SOURCES =				\
+	decl.h								\
+	manager.h manager.c					\
+	tokens.l							\
+	grammar.y
+
+
+# Automake fait les choses à moitié
+CLEANFILES = grammar.h grammar.c grammar.output tokens.c tokens.h
diff --git a/tools/d2c/hooks/decl.h b/tools/d2c/hooks/decl.h
new file mode 100644
index 0000000..7db5640
--- /dev/null
+++ b/tools/d2c/hooks/decl.h
@@ -0,0 +1,37 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * decl.h - déclarations de prototypes utiles
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _TOOLS_D2C_HOOKS_DECL_H
+#define _TOOLS_D2C_HOOKS_DECL_H
+
+
+#include "manager.h"
+
+
+
+/* Interprête des données relatives à un champ de bits. */
+bool load_hooks_from_raw_line(instr_hooks *, const char *);
+
+
+
+#endif  /* _TOOLS_D2C_HOOKS_DECL_H */
diff --git a/tools/d2c/hooks/grammar.y b/tools/d2c/hooks/grammar.y
new file mode 100644
index 0000000..43e7ba0
--- /dev/null
+++ b/tools/d2c/hooks/grammar.y
@@ -0,0 +1,109 @@
+
+%{
+
+#include "tokens.h"
+
+
+/* Affiche un message d'erreur suite à l'analyse en échec. */
+static int yyerror(instr_hooks *, char *);
+
+%}
+
+
+%code requires {
+
+#include "decl.h"
+
+}
+
+
+%union {
+
+    char *string;                           /* Chaîne de caractères        */
+
+}
+
+
+%define api.pure full
+
+%parse-param { instr_hooks *hooks }
+
+%code provides {
+
+#define YY_DECL \
+    int hooks_lex(YYSTYPE *yylvalp)
+
+YY_DECL;
+
+}
+
+
+%token NAME EQ
+
+%type <string> NAME
+
+
+%%
+
+
+hookings : /* empty */
+         | hookings hooking
+
+hooking : NAME EQ NAME { register_hook_function(hooks, $1, $3); }
+
+
+%%
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : hooks = structure impliquée dans le processus.               *
+*                msg   = message d'erreur.                                    *
+*                                                                             *
+*  Description : Affiche un message d'erreur suite à l'analyse en échec.      *
+*                                                                             *
+*  Retour      : 0                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int yyerror(instr_hooks *hooks, char *msg)
+{
+	printf("hooks yyerror line %d: %s\n", yyget_lineno(), msg);
+
+	return 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : hooks = structure à constituer à partir de données lues.     *
+*                raw   = données brutes à analyser.                           *
+*                                                                             *
+*  Description : Interprête des données relatives à un champ de bits.         *
+*                                                                             *
+*  Retour      : true si l'opération s'est bien déroulée, false sinon.        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool load_hooks_from_raw_line(instr_hooks *hooks, const char *raw)
+{
+    bool result;                            /* Bilan à faire remonter      */
+    YY_BUFFER_STATE state;                  /* Support d'analyse           */
+    int status;                             /* Bilan de l'analyse          */
+
+    state = yy_scan_string(raw);
+
+    status = yyparse(hooks);
+
+    result = (status == 0);
+
+    yy_delete_buffer(state);
+
+    return result;
+
+}
diff --git a/tools/d2c/hooks/manager.c b/tools/d2c/hooks/manager.c
new file mode 100644
index 0000000..8e7ae77
--- /dev/null
+++ b/tools/d2c/hooks/manager.c
@@ -0,0 +1,169 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * manager.c - prise en compte d'une syntaxe du langage d'assemblage
+ *
+ * Copyright (C) 2014 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "manager.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include "../helpers.h"
+
+
+
+/* Paramèter d'une fonction de renvoi */
+typedef struct _instr_func
+{
+    char *type;                             /* Type de fonction définie    */
+    char *name;                             /* Désignation humaine         */
+
+} instr_func;
+
+/* Liste des fonctions de renvoi pour une instruction */
+struct _instr_hooks
+{
+    instr_func *funcs;                      /* Liste de fonctions présentes*/
+    size_t func_count;                      /* Taille de cette liste       */
+
+};
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée une liste de fonctions à lier à une instruction.        *
+*                                                                             *
+*  Retour      : Nouvelle structure prête à emploi.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+instr_hooks *create_instr_hooks(void)
+{
+    instr_hooks *result;                    /* Définition vierge à renvoyer*/
+
+    result = (instr_hooks *)calloc(1, sizeof(instr_hooks));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : hooks = gestionnaire d'un ensemble de fonctions associées.   *
+*                                                                             *
+*  Description : Supprime de la mémoire une liste de fonctions liées.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void delete_instr_hooks(instr_hooks *hooks)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < hooks->func_count; i++)
+    {
+        free(hooks->funcs[i].type);
+        free(hooks->funcs[i].name);
+    }
+
+    if (hooks->funcs != NULL)
+        free(hooks->funcs);
+
+    free(hooks);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : hooks = gestionnaire d'un ensemble de fonctions associées.   *
+*                type  = type de fonction à enregistrer pour une instruction. *
+*                name  = désignation de la fonction à associer.               *
+*                                                                             *
+*  Description : Enregistre l'utilité d'une fonction pour une instruction.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void register_hook_function(instr_hooks *hooks, char *type, char *name)
+{
+    instr_func *func;                       /* Nouvelle prise en compte    */
+
+    hooks->funcs = (instr_func *)realloc(hooks->funcs, ++hooks->func_count * sizeof(instr_func));
+
+    func = &hooks->funcs[hooks->func_count - 1];
+
+    func->type = make_string_upper(type);
+    func->name = strdup(name);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : hooks = gestionnaire d'un ensemble de fonctions associées.   *
+*                fd    = descripteur d'un flux ouvert en écriture.            *
+*                                                                             *
+*  Description : Associe dans le code des fonctions à une instruction.        *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool write_hook_functions(const instr_hooks *hooks, int fd)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t i;                               /* Boucle de parcours          */
+    instr_func *func;                       /* Nouvelle prise en compte    */
+
+    result = true;
+
+    for (i = 0; i < hooks->func_count && result; i++)
+    {
+        func = &hooks->funcs[i];
+
+        dprintf(fd, "\t\tg_arch_instruction_set_hook(instr, IPH_%s, (instr_hook_fc)%s);\n",
+                func->type, func->name);
+
+    }
+
+    if (hooks->func_count > 0 && result)
+        dprintf(fd, "\n");
+
+    return result;
+
+}
diff --git a/tools/d2c/hooks/manager.h b/tools/d2c/hooks/manager.h
new file mode 100644
index 0000000..e3d51b6
--- /dev/null
+++ b/tools/d2c/hooks/manager.h
@@ -0,0 +1,51 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * manager.h - prototypes pour la prise en compte d'une hookse du langage d'assemblage
+ *
+ * Copyright (C) 2014 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _TOOLS_D2C_HOOKS_MANAGER_H
+#define _TOOLS_D2C_HOOKS_MANAGER_H
+
+
+#include <stdbool.h>
+
+
+
+/* Liste des fonctions de renvoi pour une instruction */
+typedef struct _instr_hooks instr_hooks;
+
+
+
+/* Crée une liste de fonctions à lier à une instruction. */
+instr_hooks *create_instr_hooks(void);
+
+/* Supprime de la mémoire une liste de fonctions liées. */
+void delete_instr_hooks(instr_hooks *);
+
+/* Enregistre l'utilité d'une fonction pour une instruction. */
+void register_hook_function(instr_hooks *, char *, char *);
+
+/* Associe dans le code des fonctions à une instruction. */
+bool write_hook_functions(const instr_hooks *, int);
+
+
+
+#endif  /* _TOOLS_D2C_HOOKS_MANAGER_H */
diff --git a/tools/d2c/hooks/tokens.l b/tools/d2c/hooks/tokens.l
new file mode 100644
index 0000000..6aebe87
--- /dev/null
+++ b/tools/d2c/hooks/tokens.l
@@ -0,0 +1,26 @@
+
+%top {
+
+#include "grammar.h"
+
+}
+
+
+%option noyywrap
+%option nounput
+%option noinput
+%option yylineno
+%option noyy_top_state
+
+
+%%
+
+
+" "                     { }
+
+[ \t\n]+                { }
+[a-z_][a-z0-9_]*        { yylvalp->string = strdup(yytext); return NAME; }
+"="                     { return EQ; }
+
+
+%%
diff --git a/tools/d2c/manual.h b/tools/d2c/manual.h
new file mode 100644
index 0000000..1402ca5
--- /dev/null
+++ b/tools/d2c/manual.h
@@ -0,0 +1,65 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * manual.h - définitions de macros pour la lecture manuelle de lexèmes
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _TOOLS_D2C_MANUAL_H
+#define _TOOLS_D2C_MANUAL_H
+
+
+#define read_block(tmp)         \
+    ({                          \
+        unsigned int __depth;       \
+        bool __is_string;           \
+        char *__iter;               \
+        \
+        __depth = 1;                    \
+    __is_string = false;                    \
+                    \
+    for (__iter = temp; __depth > 0; __iter += (__depth > 0 ? 1 : 0))                    \
+    {                    \
+        *__iter = input();                    \
+                    \
+        switch (*__iter)                    \
+        {                    \
+            case '"':                    \
+                __is_string = !__is_string;                    \
+                break;                    \
+                    \
+            case '{':                    \
+                if (!__is_string) __depth++;                    \
+                break;                    \
+                    \
+            case '}':                    \
+                if (!__is_string) __depth--;                    \
+                break;                    \
+                    \
+        }                    \
+                    \
+    }                    \
+                    \
+    *__iter = '\0';                    \
+                    \
+    printf("\n\nBLOCK\n''''\n%s\n''''\n\n", temp);                    \
+    })
+
+
+#endif  /* _TOOLS_D2C_MANUAL_H */
diff --git a/tools/d2c/pproc.h b/tools/d2c/pproc.h
index 6675fa1..2a7b6c8 100644
--- a/tools/d2c/pproc.h
+++ b/tools/d2c/pproc.h
@@ -21,8 +21,8 @@
  */
 
 
-#ifndef _TOOLS_PPROC_H
-#define _TOOLS_PPROC_H
+#ifndef _TOOLS_D2C_PPROC_H
+#define _TOOLS_D2C_PPROC_H
 
 
 #include <sys/types.h>
@@ -64,4 +64,4 @@ const char *find_macro(const pre_processor *, const char *);
 
 
 
-#endif  /* _TOOLS_PPROC_H */
+#endif  /* _TOOLS_D2C_PPROC_H */
diff --git a/tools/d2c/qckcall.h b/tools/d2c/qckcall.h
index 42aa3db..2d16048 100644
--- a/tools/d2c/qckcall.h
+++ b/tools/d2c/qckcall.h
@@ -21,18 +21,17 @@
  */
 
 
-#ifndef _TOOLS_QCKCALL_H
-#define _TOOLS_QCKCALL_H
+#ifndef _TOOLS_D2C_QCKCALL_H
+#define _TOOLS_D2C_QCKCALL_H
 
 
 #include <stdbool.h>
 
 
-
-#include "args.h"
-#include "conv.h"
-#include "bits.h"
 #include "pproc.h"
+#include "args/manager.h"
+#include "bits/manager.h"
+#include "conv/manager.h"
 
 
 
@@ -44,4 +43,4 @@ bool checked_call_instr_func(const char *, const arg_list_t *, int, const coding
 
 
 
-#endif  /* _TOOLS_QCKCALL_H */
+#endif  /* _TOOLS_D2C_QCKCALL_H */
diff --git a/tools/d2c/rules.c b/tools/d2c/rules.c
deleted file mode 100644
index d527454..0000000
--- a/tools/d2c/rules.c
+++ /dev/null
@@ -1,531 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * rules.h - prototypes pour les variations de décodage selon certaines conditions
- *
- * Copyright (C) 2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  OpenIDA is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  OpenIDA is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "rules.h"
-
-
-#include <malloc.h>
-#include <stdbool.h>
-#include <string.h>
-
-
-#include "helpers.h"
-#include "qckcall.h"
-
-
-
-/* -------------------------- CONDITIONS DE DECLENCHEMENTS -------------------------- */
-
-
-/* Expression d'une condition */
-struct _cond_expr
-{
-    bool is_simple;                         /* Sélection de champ          */
-
-    union
-    {
-        struct
-        {
-            char *variable;                 /* Variable manipulée          */
-            CondCompType comp;              /* Type de comparaison         */
-            char *value;                    /* Valeur binaire comparée     */
-
-            bool is_binary;                 /* Binaire ou hexadécimal      */
-
-        } simple;
-
-        struct
-        {
-            cond_expr *a;                   /* Première sous-expression    */
-            CondOpType operator;            /* Relation entre expressions  */
-            cond_expr *b;                   /* Seconde sous-expression     */
-
-        } composed;
-
-    };
-
-};
-
-
-/* Libère de la mémoire une expression conditionnelle. */
-static void delete_cond_expr(cond_expr *);
-
-/* Traduit en code une expression de condition. */
-static bool write_cond_expr(const cond_expr *, int, const coding_bits *);
-
-
-
-/* ------------------------- REGLES ET ACTIONS CONSEQUENTES ------------------------- */
-
-
-/* Règle particulière */
-typedef struct _extra_rule
-{
-    cond_expr *expr;                        /* Expression de déclenchement */
-    rule_action action;                     /* Conséquence d'une validation*/
-
-} extra_rule;
-
-/* Règles de décodage supplémentaires */
-struct _decoding_rules
-{
-    extra_rule *extra;                      /* Règles conditionnelles      */
-    size_t extra_count;                     /* Nombre de ces règles        */
-
-};
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                            CONDITIONS DE DECLENCHEMENTS                            */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : variable  = désignation de la variable à manipuler.          *
-*                comp      = type de comparaison à utiliser.                  *
-*                value     = valeur binaire à comparer.                       *
-*                is_binary = indique la nature de la valeur transmise.        *
-*                                                                             *
-*  Description : Crée une expression conditionnelle simple.                   *
-*                                                                             *
-*  Retour      : Structure mise en place.                                     *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-cond_expr *build_simple_cond_expression(char *variable, CondCompType comp, char *value, bool is_binary)
-{
-    cond_expr *result;                      /* Structure à retourner       */
-
-    result = (cond_expr *)calloc(1, sizeof(cond_expr));
-
-    result->is_simple = true;
-
-    result->simple.variable = make_string_lower(variable);
-    result->simple.comp = comp;
-    result->simple.value = value;
-
-    result->simple.is_binary = is_binary;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : a        = première expression à intégrer.                   *
-*                operator = type de comparaison à utiliser.                   *
-*                b        = second expression à intégrer.                     *
-*                                                                             *
-*  Description : Crée une expression conditionnelle composée.                 *
-*                                                                             *
-*  Retour      : Structure mise en place.                                     *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-cond_expr *build_composed_cond_expression(cond_expr *a, CondOpType operator, cond_expr *b)
-{
-    cond_expr *result;                      /* Structure à retourner       */
-
-    result = (cond_expr *)calloc(1, sizeof(cond_expr));
-
-    result->is_simple = false;
-
-    result->composed.a = a;
-    result->composed.operator = operator;
-    result->composed.b = b;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : expr = représentation d'expression à traiter.                *
-*                                                                             *
-*  Description : Libère de la mémoire une expression conditionnelle.          *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void delete_cond_expr(cond_expr *expr)
-{
-    if (expr->is_simple)
-    {
-        free(expr->simple.variable);
-        free(expr->simple.value);
-    }
-    else
-    {
-        delete_cond_expr(expr->composed.a);
-        delete_cond_expr(expr->composed.b);
-    }
-
-    free(expr);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : expr = expression simple ou composée à transposer.           *
-*                fd   = descripteur d'un flux ouvert en écriture.             *
-*                bits = gestionnaire des bits d'encodage.                     *
-*                                                                             *
-*  Description : Traduit en code une expression de condition.                 *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool write_cond_expr(const cond_expr *expr, int fd, const coding_bits *bits)
-{
-    bool result;                            /* Bilan à renvoyer            */
-    const raw_bitfield *bf;                 /* Champ de bits de définition */
-    unsigned int provided;                  /* Nombre de bits fournis      */
-
-    result = true;
-
-    dprintf(fd, "(");
-
-    if (expr->is_simple)
-    {
-        bf = find_named_field_in_bits(bits, expr->simple.variable);
-        if (bf == NULL)
-        {
-            fprintf(stderr, "Error: no bitfield defined the requested variable '%s'.\n", expr->simple.variable);
-            result = false;
-            goto wce_exit;
-        }
-
-        if (expr->simple.is_binary)
-            provided = strlen(expr->simple.value);
-        else
-            provided = 4 * strlen(expr->simple.value);
-
-        if (get_raw_bitfield_length(bf) != provided)
-        {
-            fprintf(stderr, "Error: variable '%s' and provided value sizes do not match (%u vs %u).\n",
-                    expr->simple.variable, get_raw_bitfield_length(bf), provided);
-            result = false;
-            goto wce_exit;
-        }
-
-        dprintf(fd, "raw_%s", expr->simple.variable);
-
-        switch (expr->simple.comp)
-        {
-            case CCT_EQUAL:
-                dprintf(fd, " == ");
-                break;
-            case CCT_DIFF:
-                dprintf(fd, " != ");
-                break;
-            case CCT_AND:
-                dprintf(fd, " & ");
-                break;
-        }
-
-        if (expr->simple.is_binary)
-            dprintf(fd, "b%s", expr->simple.value);
-        else
-            dprintf(fd, "0x%s", expr->simple.value);
-
-    }
-    else
-    {
-        result = write_cond_expr(expr->composed.a, fd, bits);
-        if (!result) goto wce_exit;
-
-        switch (expr->composed.operator)
-        {
-            case COT_AND:
-                dprintf(fd, " && ");
-                break;
-            case COT_OR:
-                dprintf(fd, " || ");
-                break;
-        }
-
-        result = write_cond_expr(expr->composed.b, fd, bits);
-        if (!result) goto wce_exit;
-
-    }
-
-    dprintf(fd, ")");
-
- wce_exit:
-
-    return result;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                           REGLES ET ACTIONS CONSEQUENTES                           */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : -                                                            *
-*                                                                             *
-*  Description : Crée un nouveau rassemblement de règles de décodage.         *
-*                                                                             *
-*  Retour      : Nouvelle structure prête à emploi.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-decoding_rules *create_decoding_rules(void)
-{
-    decoding_rules *result;                       /* Définition vierge à renvoyer*/
-
-    result = (decoding_rules *)calloc(1, sizeof(decoding_rules));
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : rules = ensemble de règles de décodage à supprimer.          *
-*                                                                             *
-*  Description : Supprime de la mémoire un ensemble de règles supplémentaires.*
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void delete_decoding_rules(decoding_rules *rules)
-{
-    size_t i;                               /* Boucle de parcours          */
-    extra_rule *rule;                       /* Règle à traiter             */
-
-    for (i = 0; i < rules->extra_count; i++)
-    {
-        rule = &rules->extra[i];
-
-        if (rule->expr != NULL)
-            delete_cond_expr(rule->expr);
-
-        switch (rule->action.type)
-        {
-            case CAT_SEE:
-                free(rule->action.details);
-                break;
-
-            case CAT_UNPREDICTABLE:
-                break;
-
-            case CAT_CALL:
-            case CAT_CHECKED_CALL:
-                free(rule->action.callee);
-                delete_arg_list(rule->action.args);
-                break;
-
-        }
-
-    }
-
-    if (rules->extra != NULL)
-        free(rules->extra);
-
-    free(rules);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : rules   = ensemble de règles à compléter.                    *
-*                expr    = représentation d'expression à conserver.           *
-*                action  = conséquence associée à la règle.                   *
-*                                                                             *
-*  Description : Ajoute une règle complète à la définition d'un codage.       *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void register_conditional_rule(decoding_rules *rules, cond_expr *expr, const rule_action *action)
-{
-    extra_rule *rule;                       /* Nouvelle prise en compte    */
-
-    rules->extra = (extra_rule *)realloc(rules->extra, ++rules->extra_count * sizeof(extra_rule));
-
-    rule = &rules->extra[rules->extra_count - 1];
-
-    rule->expr = expr;
-    rule->action = *action;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : rules   = ensemble de règles à consulter.                    *
-*                filter  = filtre sur les règles à effectivement imprimer.    *
-*                fd      = descripteur d'un flux ouvert en écriture.          *
-*                arch    = architecture visée par l'opération.                *
-*                subarch = sous-catégorie de cette même architecture.         *
-*                bits    = gestionnaire des bits d'encodage.                  *
-*                list    = liste de l'ensemble des fonctions de conversion.   *
-*                pp      = pré-processeur pour les échanges de chaînes.       *
-*                exit    = exprime le besoin d'une voie de sortie. [OUT]      *
-*                                                                             *
-*  Description : Traduit en code les éventuelles règles présentes.            *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool write_decoding_rules(decoding_rules *rules, CondActionType filter, int fd, const char *arch, const char *subarch, const coding_bits *bits, const conv_list *list, const pre_processor *pp, bool *exit)
-{
-    bool result;                            /* Bilan à remonter            */
-    size_t i;                               /* Boucle de parcours          */
-    const extra_rule *rule;                 /* Règle en cours d'écriture   */
-    bool multi_lines;                       /* Nécessite des accolades     */
-    const char *callable;                   /* Fonction à appeler          */
-
-    result = true;
-
-    for (i = 0; i < rules->extra_count; i++)
-    {
-        rule = &rules->extra[i];
-
-        if (rule->action.type != filter)
-            continue;
-
-        switch (rule->action.type)
-        {
-            case CAT_CALL:
-                multi_lines = false;
-                break;
-
-            default:
-                multi_lines = true;
-                break;
-
-        }
-
-        if (rule->expr != NULL)
-        {
-            dprintf(fd, "\t\tif ");
-
-            result = write_cond_expr(rule->expr, fd, bits);
-            if (!result) break;
-
-            dprintf(fd, "\n");
-
-            if (multi_lines)
-                dprintf(fd, "\t\t{\n");
-
-        }
-
-        switch (rule->action.type)
-        {
-            case CAT_SEE:
-
-#if 0
-                dprintf(fd, "\t\t\tinstr = %s_read_%sinstr_%s", arch, subarch, rule->action.details);
-
-                /* TODO : adapter les paramètres d'appel selon le 'coder' */
-                dprintf(fd, "(_raw);\n");
-
-                dprintf(fd, "\t\t\tgoto quick_exit;\n");
-
-                *exit = true;
-#endif
-                break;
-
-            case CAT_UNPREDICTABLE:
-                break;
-
-            case CAT_CALL:
-
-                callable = find_macro(pp, rule->action.callee);
-
-                if (callable == NULL)
-                    callable = rule->action.callee;
-
-                if (rule->expr != NULL)
-                    dprintf(fd, "\t");
-
-                result = call_instr_func(callable, rule->action.args, fd, bits, list, pp);
-
-                break;
-
-            case CAT_CHECKED_CALL:
-
-                callable = find_macro(pp, rule->action.callee);
-
-                if (callable == NULL)
-                    callable = rule->action.callee;
-
-                if (rule->expr != NULL)
-                    dprintf(fd, "\t");
-
-                result = checked_call_instr_func(callable, rule->action.args, fd, bits, list, pp);
-
-                if (rule->expr != NULL)
-                    dprintf(fd, "\t");
-
-                dprintf(fd, "\t\t\tgoto quick_exit;\n");
-
-                *exit = true;
-                break;
-
-        }
-
-        if (rule->expr != NULL && multi_lines)
-            dprintf(fd, "\t\t}\n");
-
-        dprintf(fd, "\n");
-
-    }
-
-    return result;
-
-}
diff --git a/tools/d2c/rules.h b/tools/d2c/rules.h
deleted file mode 100644
index cac6a55..0000000
--- a/tools/d2c/rules.h
+++ /dev/null
@@ -1,120 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * rules.h - prototypes pour les variations de décodage selon certaines conditions
- *
- * Copyright (C) 2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  OpenIDA is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  OpenIDA is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _TOOLS_RULES_H
-#define _TOOLS_RULES_H
-
-
-#include "args.h"
-#include "bits.h"
-#include "conv.h"
-#include "pproc.h"
-
-
-
-/* -------------------------- CONDITIONS DE DECLENCHEMENTS -------------------------- */
-
-
-/* Types de comparaison */
-typedef enum _CondCompType
-{
-    CCT_EQUAL,                              /* Egalité '=='                */
-    CCT_DIFF,                               /* Différence '!='             */
-    CCT_AND                                 /* Et logique '&'              */
-
-} CondCompType;
-
-/* Types de combinaison d'expressions */
-typedef enum _CondOpType
-{
-    COT_AND,                                /* Combinaison ET ('&&')       */
-    COT_OR                                  /* Combinaison OU ('||')       */
-
-} CondOpType;
-
-/* Expression d'une condition */
-typedef struct _cond_expr cond_expr;
-
-
-/* Crée une expression conditionnelle simple. */
-cond_expr *build_simple_cond_expression(char *, CondCompType, char *, bool);
-
-/* Crée une expression conditionnelle composée. */
-cond_expr *build_composed_cond_expression(cond_expr *, CondOpType, cond_expr *);
-
-
-
-/* ------------------------- REGLES ET ACTIONS CONSEQUENTES ------------------------- */
-
-
-/* Conséquence en cas de condition remplie */
-typedef enum _CondActionType
-{
-    CAT_SEE,                                /* Renvoi vers une instruction */
-    CAT_UNPREDICTABLE,                      /* Cas de figure improbable    */
-    CAT_CALL,                               /* Appel à une fonction C      */
-    CAT_CHECKED_CALL                        /* Appel à une fonction C      */
-
-} CondActionType;
-
-/* Définition d'une action de règle */
-typedef struct _rule_action
-{
-    CondActionType type;                    /* Conséquence d'une validation*/
-
-    union
-    {
-        /* CAT_SEE */
-        char *details;                      /* Eventuel complément d'info. */
-
-        /* CAT_CALL */
-        struct
-        {
-            char *callee;                   /* Fonction appelée            */
-            arg_list_t *args;               /* Arguments à fournir         */
-
-        };
-
-    };
-
-} rule_action;
-
-/* Règles de décodage supplémentaires */
-typedef struct _decoding_rules decoding_rules;
-
-
-/* Crée un nouveau rassemblement de règles de décodage. */
-decoding_rules *create_decoding_rules(void);
-
-/* Supprime de la mémoire un ensemble de règles supplémentaires. */
-void delete_decoding_rules(decoding_rules *);
-
-/* Ajoute une règle complète à la définition d'un codage. */
-void register_conditional_rule(decoding_rules *, cond_expr *, const rule_action *);
-
-/* Traduit en code les éventuelles règles présentes. */
-bool write_decoding_rules(decoding_rules *, CondActionType, int, const char *, const char *, const coding_bits *, const conv_list *, const pre_processor *, bool *);
-
-
-
-#endif  /* _TOOLS_RULES_H */
diff --git a/tools/d2c/rules/Makefile.am b/tools/d2c/rules/Makefile.am
new file mode 100644
index 0000000..c2d9d96
--- /dev/null
+++ b/tools/d2c/rules/Makefile.am
@@ -0,0 +1,31 @@
+
+BUILT_SOURCES = grammar.h
+
+
+# On évite d'utiliser les variables personnalisées de type *_la_[YL]FLAGS
+# afin de conserver des noms de fichiers simples, ie sans le nom de la
+# bibliothèque de sortie en préfixe.
+
+AM_YFLAGS = -v -d -p rules_
+
+AM_LFLAGS = -P rules_ -o lex.yy.c --header-file=tokens.h		\
+			-Dyylval=rules_lval -Dyyget_lineno=rules_get_lineno \
+			-Dyy_scan_string=rules__scan_string					\
+			-Dyy_delete_buffer=rules__delete_buffer
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS)
+
+
+noinst_LTLIBRARIES  = libd2crules.la
+
+.NOTPARALLEL: $(noinst_LTLIBRARIES)
+
+libd2crules_la_SOURCES =				\
+	decl.h								\
+	manager.h manager.c					\
+	tokens.l							\
+	grammar.y
+
+
+# Automake fait les choses à moitié
+CLEANFILES = grammar.h grammar.c grammar.output tokens.c tokens.h
diff --git a/tools/d2c/rules/decl.h b/tools/d2c/rules/decl.h
new file mode 100644
index 0000000..f7d7960
--- /dev/null
+++ b/tools/d2c/rules/decl.h
@@ -0,0 +1,37 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * decl.h - déclarations de prototypes utiles
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _TOOLS_D2C_RULES_DECL_H
+#define _TOOLS_D2C_RULES_DECL_H
+
+
+#include "manager.h"
+
+
+
+/* Interprête des données relatives à un bloc règles. */
+bool load_rules_from_raw_block(decoding_rules *, const char *);
+
+
+
+#endif  /* _TOOLS_D2C_RULES_DECL_H */
diff --git a/tools/d2c/rules/grammar.y b/tools/d2c/rules/grammar.y
new file mode 100644
index 0000000..effd4b3
--- /dev/null
+++ b/tools/d2c/rules/grammar.y
@@ -0,0 +1,162 @@
+
+%{
+
+#include "tokens.h"
+#include "../helpers.h"
+
+
+/* Affiche un message d'erreur suite à l'analyse en échec. */
+static int yyerror(decoding_rules *, char *);
+
+%}
+
+
+%code requires {
+
+#include "decl.h"
+#include "../args/decl.h"
+
+}
+
+
+%union {
+
+    char *string;                           /* Chaîne de caractères #1     */
+    const char *cstring;                    /* Chaîne de caractères #2     */
+
+    cond_expr *expr;                        /* Expression de déclenchement */
+    rule_action raction;                    /* Action et éléments associés */
+}
+
+
+%define api.pure full
+
+%parse-param { decoding_rules *rules }
+
+%code provides {
+
+#define YY_DECL \
+    int rules_lex(YYSTYPE *yylvalp)
+
+YY_DECL;
+
+}
+
+
+%token IF EXPR_START EXPR_END THEN
+
+%token SEE CALL CHK_CALL UNPREDICTABLE
+
+%token NAME
+
+%token EQUAL BINVAL HEXVAL
+
+%token AND AND_LOG
+
+%token RAW_LINE
+
+
+%type <string> NAME
+
+%type <cstring> RAW_LINE
+
+%type <expr> rule_cond
+%type <string> BINVAL HEXVAL
+%type <raction> action
+
+
+%%
+
+
+rules_list : /* empty */
+           | rules_list rule
+
+rule : IF EXPR_START rule_cond EXPR_END THEN action { register_conditional_rule(rules, $3, &$6); }
+     | action                                       { register_conditional_rule(rules, NULL, &$1); }
+
+rule_cond : NAME EQUAL BINVAL   { $$ = build_simple_cond_expression($1, CCT_EQUAL, $3, true); }
+          | NAME EQUAL HEXVAL   { $$ = build_simple_cond_expression($1, CCT_EQUAL, $3, false); }
+          | NAME AND_LOG BINVAL { $$ = build_simple_cond_expression($1, CCT_AND, $3, true); }
+          | NAME AND_LOG HEXVAL { $$ = build_simple_cond_expression($1, CCT_AND, $3, false); }
+          | EXPR_START rule_cond EXPR_END AND EXPR_START rule_cond EXPR_END
+                                { $$ = build_composed_cond_expression($2, COT_AND, $6); }
+
+action : SEE RAW_LINE       { $$.type = CAT_SEE; $$.details = make_callable($2, false); }
+       | UNPREDICTABLE      { $$.type = CAT_UNPREDICTABLE; }
+       | CALL RAW_LINE      {
+                                right_op_t rop;
+                                bool status;
+
+                                status = load_call_from_raw_line(&rop, $2);
+                                if (!status) YYABORT;
+
+                                $$.type = CAT_CALL; $$.callee = rop.func; $$.args = rop.args;
+
+                            }
+       | CHK_CALL RAW_LINE  {
+                                right_op_t rop;
+                                bool status;
+
+                                status = load_call_from_raw_line(&rop, $2);
+                                if (!status) YYABORT;
+
+                                $$.type = CAT_CHECKED_CALL; $$.callee = rop.func; $$.args = rop.args;
+
+                            }
+
+
+%%
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : rules = structure impliquée dans le processus.               *
+*                msg   = message d'erreur.                                    *
+*                                                                             *
+*  Description : Affiche un message d'erreur suite à l'analyse en échec.      *
+*                                                                             *
+*  Retour      : 0                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int yyerror(decoding_rules *rules, char *msg)
+{
+	printf("yyerror line %d: %s\n", yyget_lineno(), msg);
+
+	return 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : rules = structure à constituer à partir de données lues.     *
+*                raw   = données brutes à analyser.                           *
+*                                                                             *
+*  Description : Interprête des données relatives à un bloc règles.           *
+*                                                                             *
+*  Retour      : true si l'opération s'est bien déroulée, false sinon.        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool load_rules_from_raw_block(decoding_rules *rules, const char *raw)
+{
+    bool result;                            /* Bilan à faire remonter      */
+    YY_BUFFER_STATE state;                  /* Support d'analyse           */
+    int status;                             /* Bilan de l'analyse          */
+
+    state = yy_scan_string(raw);
+
+    status = yyparse(rules);
+
+    result = (status == 0);
+
+    yy_delete_buffer(state);
+
+    return result;
+
+}
diff --git a/tools/d2c/rules/manager.c b/tools/d2c/rules/manager.c
new file mode 100644
index 0000000..f30559e
--- /dev/null
+++ b/tools/d2c/rules/manager.c
@@ -0,0 +1,531 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * manager.h - prototypes pour les variations de décodage selon certaines conditions
+ *
+ * Copyright (C) 2014 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "manager.h"
+
+
+#include <malloc.h>
+#include <stdbool.h>
+#include <string.h>
+
+
+#include "../helpers.h"
+#include "../qckcall.h"
+
+
+
+/* -------------------------- CONDITIONS DE DECLENCHEMENTS -------------------------- */
+
+
+/* Expression d'une condition */
+struct _cond_expr
+{
+    bool is_simple;                         /* Sélection de champ          */
+
+    union
+    {
+        struct
+        {
+            char *variable;                 /* Variable manipulée          */
+            CondCompType comp;              /* Type de comparaison         */
+            char *value;                    /* Valeur binaire comparée     */
+
+            bool is_binary;                 /* Binaire ou hexadécimal      */
+
+        } simple;
+
+        struct
+        {
+            cond_expr *a;                   /* Première sous-expression    */
+            CondOpType operator;            /* Relation entre expressions  */
+            cond_expr *b;                   /* Seconde sous-expression     */
+
+        } composed;
+
+    };
+
+};
+
+
+/* Libère de la mémoire une expression conditionnelle. */
+static void delete_cond_expr(cond_expr *);
+
+/* Traduit en code une expression de condition. */
+static bool write_cond_expr(const cond_expr *, int, const coding_bits *);
+
+
+
+/* ------------------------- REGLES ET ACTIONS CONSEQUENTES ------------------------- */
+
+
+/* Règle particulière */
+typedef struct _extra_rule
+{
+    cond_expr *expr;                        /* Expression de déclenchement */
+    rule_action action;                     /* Conséquence d'une validation*/
+
+} extra_rule;
+
+/* Règles de décodage supplémentaires */
+struct _decoding_rules
+{
+    extra_rule *extra;                      /* Règles conditionnelles      */
+    size_t extra_count;                     /* Nombre de ces règles        */
+
+};
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                            CONDITIONS DE DECLENCHEMENTS                            */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : variable  = désignation de la variable à manipuler.          *
+*                comp      = type de comparaison à utiliser.                  *
+*                value     = valeur binaire à comparer.                       *
+*                is_binary = indique la nature de la valeur transmise.        *
+*                                                                             *
+*  Description : Crée une expression conditionnelle simple.                   *
+*                                                                             *
+*  Retour      : Structure mise en place.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+cond_expr *build_simple_cond_expression(char *variable, CondCompType comp, char *value, bool is_binary)
+{
+    cond_expr *result;                      /* Structure à retourner       */
+
+    result = (cond_expr *)calloc(1, sizeof(cond_expr));
+
+    result->is_simple = true;
+
+    result->simple.variable = make_string_lower(variable);
+    result->simple.comp = comp;
+    result->simple.value = value;
+
+    result->simple.is_binary = is_binary;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : a        = première expression à intégrer.                   *
+*                operator = type de comparaison à utiliser.                   *
+*                b        = second expression à intégrer.                     *
+*                                                                             *
+*  Description : Crée une expression conditionnelle composée.                 *
+*                                                                             *
+*  Retour      : Structure mise en place.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+cond_expr *build_composed_cond_expression(cond_expr *a, CondOpType operator, cond_expr *b)
+{
+    cond_expr *result;                      /* Structure à retourner       */
+
+    result = (cond_expr *)calloc(1, sizeof(cond_expr));
+
+    result->is_simple = false;
+
+    result->composed.a = a;
+    result->composed.operator = operator;
+    result->composed.b = b;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = représentation d'expression à traiter.                *
+*                                                                             *
+*  Description : Libère de la mémoire une expression conditionnelle.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void delete_cond_expr(cond_expr *expr)
+{
+    if (expr->is_simple)
+    {
+        free(expr->simple.variable);
+        free(expr->simple.value);
+    }
+    else
+    {
+        delete_cond_expr(expr->composed.a);
+        delete_cond_expr(expr->composed.b);
+    }
+
+    free(expr);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : expr = expression simple ou composée à transposer.           *
+*                fd   = descripteur d'un flux ouvert en écriture.             *
+*                bits = gestionnaire des bits d'encodage.                     *
+*                                                                             *
+*  Description : Traduit en code une expression de condition.                 *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool write_cond_expr(const cond_expr *expr, int fd, const coding_bits *bits)
+{
+    bool result;                            /* Bilan à renvoyer            */
+    const raw_bitfield *bf;                 /* Champ de bits de définition */
+    unsigned int provided;                  /* Nombre de bits fournis      */
+
+    result = true;
+
+    dprintf(fd, "(");
+
+    if (expr->is_simple)
+    {
+        bf = find_named_field_in_bits(bits, expr->simple.variable);
+        if (bf == NULL)
+        {
+            fprintf(stderr, "Error: no bitfield defined the requested variable '%s'.\n", expr->simple.variable);
+            result = false;
+            goto wce_exit;
+        }
+
+        if (expr->simple.is_binary)
+            provided = strlen(expr->simple.value);
+        else
+            provided = 4 * strlen(expr->simple.value);
+
+        if (get_raw_bitfield_length(bf) != provided)
+        {
+            fprintf(stderr, "Error: variable '%s' and provided value sizes do not match (%u vs %u).\n",
+                    expr->simple.variable, get_raw_bitfield_length(bf), provided);
+            result = false;
+            goto wce_exit;
+        }
+
+        dprintf(fd, "raw_%s", expr->simple.variable);
+
+        switch (expr->simple.comp)
+        {
+            case CCT_EQUAL:
+                dprintf(fd, " == ");
+                break;
+            case CCT_DIFF:
+                dprintf(fd, " != ");
+                break;
+            case CCT_AND:
+                dprintf(fd, " & ");
+                break;
+        }
+
+        if (expr->simple.is_binary)
+            dprintf(fd, "b%s", expr->simple.value);
+        else
+            dprintf(fd, "0x%s", expr->simple.value);
+
+    }
+    else
+    {
+        result = write_cond_expr(expr->composed.a, fd, bits);
+        if (!result) goto wce_exit;
+
+        switch (expr->composed.operator)
+        {
+            case COT_AND:
+                dprintf(fd, " && ");
+                break;
+            case COT_OR:
+                dprintf(fd, " || ");
+                break;
+        }
+
+        result = write_cond_expr(expr->composed.b, fd, bits);
+        if (!result) goto wce_exit;
+
+    }
+
+    dprintf(fd, ")");
+
+ wce_exit:
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                           REGLES ET ACTIONS CONSEQUENTES                           */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée un nouveau rassemblement de règles de décodage.         *
+*                                                                             *
+*  Retour      : Nouvelle structure prête à emploi.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+decoding_rules *create_decoding_rules(void)
+{
+    decoding_rules *result;                       /* Définition vierge à renvoyer*/
+
+    result = (decoding_rules *)calloc(1, sizeof(decoding_rules));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : rules = ensemble de règles de décodage à supprimer.          *
+*                                                                             *
+*  Description : Supprime de la mémoire un ensemble de règles supplémentaires.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void delete_decoding_rules(decoding_rules *rules)
+{
+    size_t i;                               /* Boucle de parcours          */
+    extra_rule *rule;                       /* Règle à traiter             */
+
+    for (i = 0; i < rules->extra_count; i++)
+    {
+        rule = &rules->extra[i];
+
+        if (rule->expr != NULL)
+            delete_cond_expr(rule->expr);
+
+        switch (rule->action.type)
+        {
+            case CAT_SEE:
+                free(rule->action.details);
+                break;
+
+            case CAT_UNPREDICTABLE:
+                break;
+
+            case CAT_CALL:
+            case CAT_CHECKED_CALL:
+                free(rule->action.callee);
+                delete_arg_list(rule->action.args);
+                break;
+
+        }
+
+    }
+
+    if (rules->extra != NULL)
+        free(rules->extra);
+
+    free(rules);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : rules   = ensemble de règles à compléter.                    *
+*                expr    = représentation d'expression à conserver.           *
+*                action  = conséquence associée à la règle.                   *
+*                                                                             *
+*  Description : Ajoute une règle complète à la définition d'un codage.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void register_conditional_rule(decoding_rules *rules, cond_expr *expr, const rule_action *action)
+{
+    extra_rule *rule;                       /* Nouvelle prise en compte    */
+
+    rules->extra = (extra_rule *)realloc(rules->extra, ++rules->extra_count * sizeof(extra_rule));
+
+    rule = &rules->extra[rules->extra_count - 1];
+
+    rule->expr = expr;
+    rule->action = *action;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : rules   = ensemble de règles à consulter.                    *
+*                filter  = filtre sur les règles à effectivement imprimer.    *
+*                fd      = descripteur d'un flux ouvert en écriture.          *
+*                arch    = architecture visée par l'opération.                *
+*                subarch = sous-catégorie de cette même architecture.         *
+*                bits    = gestionnaire des bits d'encodage.                  *
+*                list    = liste de l'ensemble des fonctions de conversion.   *
+*                pp      = pré-processeur pour les échanges de chaînes.       *
+*                exit    = exprime le besoin d'une voie de sortie. [OUT]      *
+*                                                                             *
+*  Description : Traduit en code les éventuelles règles présentes.            *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool write_decoding_rules(decoding_rules *rules, CondActionType filter, int fd, const char *arch, const char *subarch, const coding_bits *bits, const conv_list *list, const pre_processor *pp, bool *exit)
+{
+    bool result;                            /* Bilan à remonter            */
+    size_t i;                               /* Boucle de parcours          */
+    const extra_rule *rule;                 /* Règle en cours d'écriture   */
+    bool multi_lines;                       /* Nécessite des accolades     */
+    const char *callable;                   /* Fonction à appeler          */
+
+    result = true;
+
+    for (i = 0; i < rules->extra_count; i++)
+    {
+        rule = &rules->extra[i];
+
+        if (rule->action.type != filter)
+            continue;
+
+        switch (rule->action.type)
+        {
+            case CAT_CALL:
+                multi_lines = false;
+                break;
+
+            default:
+                multi_lines = true;
+                break;
+
+        }
+
+        if (rule->expr != NULL)
+        {
+            dprintf(fd, "\t\tif ");
+
+            result = write_cond_expr(rule->expr, fd, bits);
+            if (!result) break;
+
+            dprintf(fd, "\n");
+
+            if (multi_lines)
+                dprintf(fd, "\t\t{\n");
+
+        }
+
+        switch (rule->action.type)
+        {
+            case CAT_SEE:
+
+#if 0
+                dprintf(fd, "\t\t\tinstr = %s_read_%sinstr_%s", arch, subarch, rule->action.details);
+
+                /* TODO : adapter les paramètres d'appel selon le 'coder' */
+                dprintf(fd, "(_raw);\n");
+
+                dprintf(fd, "\t\t\tgoto quick_exit;\n");
+
+                *exit = true;
+#endif
+                break;
+
+            case CAT_UNPREDICTABLE:
+                break;
+
+            case CAT_CALL:
+
+                callable = find_macro(pp, rule->action.callee);
+
+                if (callable == NULL)
+                    callable = rule->action.callee;
+
+                if (rule->expr != NULL)
+                    dprintf(fd, "\t");
+
+                result = call_instr_func(callable, rule->action.args, fd, bits, list, pp);
+
+                break;
+
+            case CAT_CHECKED_CALL:
+
+                callable = find_macro(pp, rule->action.callee);
+
+                if (callable == NULL)
+                    callable = rule->action.callee;
+
+                if (rule->expr != NULL)
+                    dprintf(fd, "\t");
+
+                result = checked_call_instr_func(callable, rule->action.args, fd, bits, list, pp);
+
+                if (rule->expr != NULL)
+                    dprintf(fd, "\t");
+
+                dprintf(fd, "\t\t\tgoto quick_exit;\n");
+
+                *exit = true;
+                break;
+
+        }
+
+        if (rule->expr != NULL && multi_lines)
+            dprintf(fd, "\t\t}\n");
+
+        dprintf(fd, "\n");
+
+    }
+
+    return result;
+
+}
diff --git a/tools/d2c/rules/manager.h b/tools/d2c/rules/manager.h
new file mode 100644
index 0000000..f8ff2d6
--- /dev/null
+++ b/tools/d2c/rules/manager.h
@@ -0,0 +1,120 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * manager.h - prototypes pour les variations de décodage selon certaines conditions
+ *
+ * Copyright (C) 2014 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _TOOLS_D2C_RULES_MANAGER_H
+#define _TOOLS_D2C_RULES_MANAGER_H
+
+
+#include "../pproc.h"
+#include "../args/manager.h"
+#include "../bits/manager.h"
+#include "../conv/manager.h"
+
+
+
+/* -------------------------- CONDITIONS DE DECLENCHEMENTS -------------------------- */
+
+
+/* Types de comparaison */
+typedef enum _CondCompType
+{
+    CCT_EQUAL,                              /* Egalité '=='                */
+    CCT_DIFF,                               /* Différence '!='             */
+    CCT_AND                                 /* Et logique '&'              */
+
+} CondCompType;
+
+/* Types de combinaison d'expressions */
+typedef enum _CondOpType
+{
+    COT_AND,                                /* Combinaison ET ('&&')       */
+    COT_OR                                  /* Combinaison OU ('||')       */
+
+} CondOpType;
+
+/* Expression d'une condition */
+typedef struct _cond_expr cond_expr;
+
+
+/* Crée une expression conditionnelle simple. */
+cond_expr *build_simple_cond_expression(char *, CondCompType, char *, bool);
+
+/* Crée une expression conditionnelle composée. */
+cond_expr *build_composed_cond_expression(cond_expr *, CondOpType, cond_expr *);
+
+
+
+/* ------------------------- REGLES ET ACTIONS CONSEQUENTES ------------------------- */
+
+
+/* Conséquence en cas de condition remplie */
+typedef enum _CondActionType
+{
+    CAT_SEE,                                /* Renvoi vers une instruction */
+    CAT_UNPREDICTABLE,                      /* Cas de figure improbable    */
+    CAT_CALL,                               /* Appel à une fonction C      */
+    CAT_CHECKED_CALL                        /* Appel à une fonction C      */
+
+} CondActionType;
+
+/* Définition d'une action de règle */
+typedef struct _rule_action
+{
+    CondActionType type;                    /* Conséquence d'une validation*/
+
+    union
+    {
+        /* CAT_SEE */
+        char *details;                      /* Eventuel complément d'info. */
+
+        /* CAT_CALL */
+        struct
+        {
+            char *callee;                   /* Fonction appelée            */
+            arg_list_t *args;               /* Arguments à fournir         */
+
+        };
+
+    };
+
+} rule_action;
+
+/* Règles de décodage supplémentaires */
+typedef struct _decoding_rules decoding_rules;
+
+
+/* Crée un nouveau rassemblement de règles de décodage. */
+decoding_rules *create_decoding_rules(void);
+
+/* Supprime de la mémoire un ensemble de règles supplémentaires. */
+void delete_decoding_rules(decoding_rules *);
+
+/* Ajoute une règle complète à la définition d'un codage. */
+void register_conditional_rule(decoding_rules *, cond_expr *, const rule_action *);
+
+/* Traduit en code les éventuelles règles présentes. */
+bool write_decoding_rules(decoding_rules *, CondActionType, int, const char *, const char *, const coding_bits *, const conv_list *, const pre_processor *, bool *);
+
+
+
+#endif  /* _TOOLS_D2C_RULES_MANAGER_H */
diff --git a/tools/d2c/rules/tokens.l b/tools/d2c/rules/tokens.l
new file mode 100644
index 0000000..36d6c4a
--- /dev/null
+++ b/tools/d2c/rules/tokens.l
@@ -0,0 +1,57 @@
+
+%top {
+
+#include "grammar.h"
+
+}
+
+
+%option noyywrap
+%option nounput
+%option noinput
+%option yylineno
+%option stack
+%option noyy_top_state
+
+%x cond
+%x cond_binval
+%x cond_hexval
+%x action
+%x raw_line
+
+
+%%
+
+
+\/\/[^\n]+          { printf("SKIP '%s'\n", yytext); }
+
+"if"                            { yy_push_state(cond); return IF; }
+<cond>[ ]+                      { }
+<cond>"("                       { return EXPR_START; }
+<cond>[A-Za-z_][A-Za-z0-9_]*    { yylvalp->string = strdup(yytext); return NAME; }
+<cond>"=="                      { return EQUAL; }
+<cond>"'"                       { yy_push_state(cond_binval); }
+<cond_binval>[01][01]*          { yylvalp->string = strdup(yytext); return BINVAL; }
+<cond_binval>"'"                { yy_pop_state(); }
+<cond>"0x"                      { yy_push_state(cond_hexval); }
+<cond_hexval>[0-9a-f][0-9a-f]*  { yylvalp->string = strdup(yytext); yy_pop_state(); return HEXVAL; }
+<cond>")"                       { return EXPR_END; }
+<cond>"&&"                      { return AND; }
+<cond>"&"                       { return AND_LOG; }
+
+<cond>";"           { yy_pop_state(); return THEN; }
+
+[ ]                 { }
+
+"see "              { yy_push_state(raw_line); return SEE; }
+
+"unpredictable"     { return UNPREDICTABLE; }
+
+"call"              { yy_push_state(raw_line); return CALL; }
+"chk_call"          { yy_push_state(raw_line); return CHK_CALL; }
+
+<raw_line>[^\n]+    { yylvalp->cstring = yytext; return RAW_LINE; }
+<raw_line>"\n"      { yy_pop_state(); }
+
+
+%%
diff --git a/tools/d2c/spec.h b/tools/d2c/spec.h
index 39bfdb7..e09aa49 100644
--- a/tools/d2c/spec.h
+++ b/tools/d2c/spec.h
@@ -21,19 +21,19 @@
  */
 
 
-#ifndef _TOOLS_SPEC_H
-#define _TOOLS_SPEC_H
+#ifndef _TOOLS_D2C_SPEC_H
+#define _TOOLS_D2C_SPEC_H
 
 
 #include <stdbool.h>
 
 
-#include "bits.h"
-#include "conv.h"
-#include "hooks.h"
 #include "pproc.h"
-#include "rules.h"
-#include "syntax.h"
+#include "bits/manager.h"
+#include "conv/manager.h"
+#include "hooks/manager.h"
+#include "rules/manager.h"
+#include "syntax/manager.h"
 
 
 
@@ -73,4 +73,4 @@ bool write_encoding_spec_disass(const encoding_spec *, int, const char *, const
 
 
 
-#endif  /* _TOOLS_SPEC_H */
+#endif  /* _TOOLS_D2C_SPEC_H */
diff --git a/tools/d2c/syntax.c b/tools/d2c/syntax.c
deleted file mode 100644
index 96fffc5..0000000
--- a/tools/d2c/syntax.c
+++ /dev/null
@@ -1,385 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * syntax.c - prise en compte d'une syntaxe du langage d'assemblage
- *
- * Copyright (C) 2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  OpenIDA is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  OpenIDA is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "syntax.h"
-
-
-#include <malloc.h>
-#include <string.h>
-
-
-#include "helpers.h"
-
-
-
-/* Propriétés particulières pour les opérandes */
-typedef enum _SyntaxItemFlags
-{
-    SIF_NONE     = (0 << 0),                /* Aucune propriété            */
-    SIF_DECIMAL  = (1 << 0),                /* Affichage en décimal        */
-    SIF_OPTIONAL = (1 << 1)                 /* Absence tolérée             */
-
-} SyntaxItemFlags;
-
-/* Elément défini dans une syntaxe */
-typedef struct _syntax_item
-{
-    char *name;                             /* Désignation humaine         */
-    SyntaxItemType impact;                  /* Portée de l'élément         */
-    SyntaxItemFlags flags;                  /* Propriétés supplémentaires  */
-
-} syntax_item;
-
-/* Syntaxe d'une ligne d'assembleur */
-struct _asm_syntax
-{
-    syntax_item *items;                     /* Eléments de la syntaxe      */
-    size_t items_count;                     /* Nombre de ces éléments      */
-
-};
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : -                                                            *
-*                                                                             *
-*  Description : Crée un nouvel indicateur pour l'écriture d'une instruction. *
-*                                                                             *
-*  Retour      : Nouvelle structure prête à emploi.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-asm_syntax *create_asm_syntax(void)
-{
-    asm_syntax *result;                    /* Définition vierge à renvoyer*/
-
-    result = (asm_syntax *)calloc(1, sizeof(asm_syntax));
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : syntax = gestionnaire d'un ensemble d'éléments de syntaxe.   *
-*                                                                             *
-*  Description : Supprime de la mémoire un indicateur d'écriture ASM.         *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void delete_asm_syntax(asm_syntax *syntax)
-{
-    size_t i;                               /* Boucle de parcours          */
-
-    for (i = 0; i < syntax->items_count; i++)
-        free(syntax->items[i].name);
-
-    if (syntax->items != NULL)
-        free(syntax->items);
-
-    free(syntax);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : syntax = gestionnaire d'un ensemble d'éléments de syntaxe.   *
-*                name   = désignation de l'opérande dans la spécification.    *
-*                impact = précise la portée effective de l'opérande           *
-*                                                                             *
-*  Description : Enregistre la présence d'un nouvel opérande dans la syntaxe. *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void register_syntax_item(asm_syntax *syntax, char *name, SyntaxItemType impact)
-{
-    syntax_item *item;                      /* Nouvelle prise en compte    */
-    size_t len;                             /* Taille du nom fourni        */
-
-    syntax->items = (syntax_item *)realloc(syntax->items, ++syntax->items_count * sizeof(syntax_item));
-
-    item = &syntax->items[syntax->items_count - 1];
-
-    /* Récupération des drapeaux */
-
-    item->flags = SIF_NONE;
-
-    for (len = strlen(name); len > 0; len--)
-        switch (name[0])
-        {
-            case '#':
-                item->flags |= SIF_DECIMAL;
-                memmove(name, name + 1, len);
-                break;
-
-            case '?':
-                item->flags |= SIF_OPTIONAL;
-                memmove(name, name + 1, len);
-                break;
-
-            default:
-                len = 1;
-                break;
-
-        }
-
-    if (impact == SIT_KEYWORD)
-        item->name = name;
-    else
-        item->name = make_string_lower(name);
-
-    item->impact = impact;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : syntax = gestionnaire d'un ensemble d'éléments de syntaxe.   *
-*                bits   = gestionnaire des bits d'encodage.                   *
-*                list   = liste de l'ensemble des fonctions de conversion.    *
-*                                                                             *
-*  Description : Marque les champs de bits effectivement utilisés.            *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool mark_syntax_items(const asm_syntax *syntax, const coding_bits *bits, const conv_list *list)
-{
-    bool result;                            /* Bilan à retourner           */
-    size_t i;                               /* Boucle de parcours          */
-    syntax_item *item;                      /* Lien vers un opérande       */
-    conv_func *func;                        /* Fonction de conversion      */
-
-    result = true;
-
-    for (i = 0; i < syntax->items_count && result; i++)
-    {
-        item = &syntax->items[i];
-        if (item->impact == SIT_KEYWORD) continue;
-
-        func = find_named_conv_in_list(list, item->name);
-        if (func == NULL)
-        {
-            fprintf(stderr, "Error: expected conversion for '%s'.\n", item->name);
-            result = false;
-        }
-
-        result = mark_conv_func(func, bits, list);
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : syntax = gestionnaire d'un ensemble d'éléments de syntaxe.   *
-*                fd     = descripteur d'un flux ouvert en écriture.           *
-*                bits   = gestionnaire des bits d'encodage.                   *
-*                list   = liste de l'ensemble des fonctions de conversion.    *
-*                wide   = taille des mots décodés.                            *
-*                                                                             *
-*  Description : Déclare les variables C associées aux opérandes de syntaxe.  *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool declare_syntax_items(const asm_syntax *syntax, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide)
-{
-    bool result;                            /* Bilan à retourner           */
-    bool has_operand;                       /* Présence d'un opérande      */
-    size_t i;                               /* Boucle de parcours          */
-    syntax_item *item;                      /* Lien vers un opérande       */
-    conv_func *func;                        /* Fonction de conversion      */
-
-    result = true;
-
-    has_operand = false;
-
-    for (i = 0; i < syntax->items_count && result; i++)
-    {
-        item = &syntax->items[i];
-        if (item->impact == SIT_KEYWORD) continue;
-
-        has_operand |= (item->impact == SIT_EXT_OPERAND);
-
-        func = find_named_conv_in_list(list, item->name);
-        if (func == NULL)
-        {
-            fprintf(stderr, "Error: expected conversion for '%s'.\n", item->name);
-            result = false;
-        }
-
-        result &= declare_conv_func(func, fd, bits, list, wide);
-
-    }
-
-    if (has_operand)
-        dprintf(fd, "\t\tGArchOperand *op;\n");
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : syntax = gestionnaire d'un ensemble d'éléments de syntaxe.   *
-*                                                                             *
-*  Description : Fournit si elle existe un nom nouveau pour une instruction.  *
-*                                                                             *
-*  Retour      : Eventuelle chaîne de caractères trouvée ou NULL.             *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-const char *get_new_keyword_from_syntax_items(const asm_syntax *syntax)
-{
-    const char *result;                     /* Nom éventuel à renvoyer     */
-
-    result = NULL;
-
-    if (syntax->items_count > 0
-        && syntax->items[0].impact == SIT_KEYWORD)
-    {
-        result = syntax->items[0].name;
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : syntax = gestionnaire d'un ensemble d'éléments de syntaxe.   *
-*                fd     = descripteur d'un flux ouvert en écriture.           *
-*                arch   = architecture visée par l'opération globale.         *
-*                bits   = gestionnaire des bits d'encodage.                   *
-*                list   = liste de l'ensemble des fonctions de conversion.    *
-*                pp     = pré-processeur pour les échanges de chaînes.        *
-*                exit   = exprime le besoin d'une voie de sortie. [OUT]       *
-*                                                                             *
-*  Description : Définit les variables C associées aux opérandes de syntaxe.  *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool define_syntax_items(const asm_syntax *syntax, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp, bool *exit)
-{
-    bool result;                            /* Bilan à retourner           */
-    size_t i;                               /* Boucle de parcours          */
-    syntax_item *item;                      /* Lien vers un opérande       */
-    conv_func *func;                        /* Fonction de conversion      */
-    bool internal;                          /* Usage interne ou non ?      */
-
-    result = true;
-
-    for (i = 0; i < syntax->items_count && result; i++)
-    {
-        item = &syntax->items[i];
-
-        switch (item->impact)
-        {
-            case SIT_KEYWORD:
-
-                if (i > 0)
-                    dprintf(fd, "\t\tg_arch_instruction_append_suffix(instr, \"%s\");\n", item->name);
-                else
-                    continue;
-
-                break;
-
-            case SIT_INT_OPERAND:
-            case SIT_EXT_OPERAND:
-
-                internal = (item->impact == SIT_INT_OPERAND);
-
-                func = find_named_conv_in_list(list, item->name);
-                if (func == NULL)
-                {
-                    fprintf(stderr, "Error: expected conversion for '%s'.\n", item->name);
-                    result = false;
-                }
-
-                /* Appel proprement dit */
-
-                result &= define_conv_func(func, true, internal, fd, arch, bits, list, pp);
-                if (!result) break;
-
-                /* Raccordement : propriété ou opérande ? */
-
-                if (internal)
-                    dprintf(fd, "\t\t\tgoto bad_exit;\n");
-
-                else
-                {
-                    dprintf(fd, "\t\tif (op == NULL) goto bad_exit;\n");
-
-                    dprintf(fd, "\n");
-
-                    if (item->flags & SIF_DECIMAL)
-                        dprintf(fd, "\t\tg_imm_operand_set_default_display(G_IMM_OPERAND(op), IOD_DEC);\n");
-
-                    dprintf(fd, "\t\tg_arch_instruction_attach_extra_operand(instr, op);\n");
-
-                }
-
-                *exit = true;
-                break;
-
-        }
-
-        dprintf(fd, "\n");
-
-    }
-
-    return result;
-
-}
diff --git a/tools/d2c/syntax.h b/tools/d2c/syntax.h
deleted file mode 100644
index 70b3609..0000000
--- a/tools/d2c/syntax.h
+++ /dev/null
@@ -1,73 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * syntax.h - prototypes pour la prise en compte d'une syntaxe du langage d'assemblage
- *
- * Copyright (C) 2014 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  OpenIDA is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  OpenIDA is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _TOOLS_SYNTAX_H
-#define _TOOLS_SYNTAX_H
-
-
-#include <stdbool.h>
-
-
-#include "bits.h"
-#include "conv.h"
-#include "pproc.h"
-
-
-
-/* Type d'éléments de syntaxe */
-typedef enum _SyntaxItemType
-{
-    SIT_KEYWORD,                            /* Elément de l'instruction    */
-    SIT_INT_OPERAND,                        /* Propriété d'architecture    */
-    SIT_EXT_OPERAND                         /* Opérande généraliste        */
-
-} SyntaxItemType;
-
-/* Syntaxe d'une ligne d'assembleur */
-typedef struct _asm_syntax asm_syntax;
-
-
-/* Crée un nouvel indicateur pour l'écriture d'une instruction. */
-asm_syntax *create_asm_syntax(void);
-
-/* Supprime de la mémoire un indicateur d'écriture ASM. */
-void delete_asm_syntax(asm_syntax *);
-
-/* Enregistre la présence d'un nouvel opérande dans la syntaxe. */
-void register_syntax_item(asm_syntax *, char *, SyntaxItemType);
-
-/* Marque les champs de bits effectivement utilisés. */
-bool mark_syntax_items(const asm_syntax *, const coding_bits *, const conv_list *);
-
-/* Déclare les variables C associées aux opérandes de syntaxe. */
-bool declare_syntax_items(const asm_syntax *, int, const coding_bits *, const conv_list *, unsigned int);
-
-/* Fournit si elle existe un nom nouveau pour une instruction. */
-const char *get_new_keyword_from_syntax_items(const asm_syntax *);
-
-/* Définit les variables C associées aux opérandes de syntaxe. */
-bool define_syntax_items(const asm_syntax *, int, const char *, const coding_bits *, const conv_list *, const pre_processor *, bool *);
-
-
-
-#endif  /* _TOOLS_SYNTAX_H */
diff --git a/tools/d2c/syntax/Makefile.am b/tools/d2c/syntax/Makefile.am
new file mode 100644
index 0000000..716f5da
--- /dev/null
+++ b/tools/d2c/syntax/Makefile.am
@@ -0,0 +1,31 @@
+
+BUILT_SOURCES = grammar.h
+
+
+# On évite d'utiliser les variables personnalisées de type *_la_[YL]FLAGS
+# afin de conserver des noms de fichiers simples, ie sans le nom de la
+# bibliothèque de sortie en préfixe.
+
+AM_YFLAGS = -v -d -p syntax_
+
+AM_LFLAGS = -P syntax_ -o lex.yy.c --header-file=tokens.h			\
+			-Dyylval=syntax_lval -Dyyget_lineno=syntax_get_lineno 	\
+			-Dyy_scan_string=syntax__scan_string					\
+			-Dyy_delete_buffer=syntax__delete_buffer
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS)
+
+
+noinst_LTLIBRARIES  = libd2csyntax.la
+
+.NOTPARALLEL: $(noinst_LTLIBRARIES)
+
+libd2csyntax_la_SOURCES =				\
+	decl.h								\
+	manager.h manager.c					\
+	tokens.l							\
+	grammar.y
+
+
+# Automake fait les choses à moitié
+CLEANFILES = grammar.h grammar.c grammar.output tokens.c tokens.h
diff --git a/tools/d2c/syntax/decl.h b/tools/d2c/syntax/decl.h
new file mode 100644
index 0000000..38e5f6d
--- /dev/null
+++ b/tools/d2c/syntax/decl.h
@@ -0,0 +1,37 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * decl.h - déclarations de prototypes utiles
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _TOOLS_D2C_SYNTAX_DECL_H
+#define _TOOLS_D2C_SYNTAX_DECL_H
+
+
+#include "manager.h"
+
+
+
+/* Interprête des données liées à une définition de syntaxe. */
+bool load_syntax_from_raw_line(asm_syntax *, const char *);
+
+
+
+#endif  /* _TOOLS_D2C_SYNTAX_DECL_H */
diff --git a/tools/d2c/syntax/grammar.y b/tools/d2c/syntax/grammar.y
new file mode 100644
index 0000000..3952b9a
--- /dev/null
+++ b/tools/d2c/syntax/grammar.y
@@ -0,0 +1,109 @@
+
+%{
+
+#include "tokens.h"
+
+
+/* Affiche un message d'erreur suite à l'analyse en échec. */
+static int yyerror(asm_syntax *, char *);
+
+%}
+
+
+%code requires {
+
+#include "decl.h"
+
+}
+
+
+%union {
+
+    char *string;                           /* Chaîne de caractères        */
+
+}
+
+
+%define api.pure full
+
+%parse-param { asm_syntax *syntax }
+
+%code provides {
+
+#define YY_DECL \
+    int syntax_lex(YYSTYPE *yylvalp)
+
+YY_DECL;
+
+}
+
+
+%token OPERAND_NAME OPERAND_INTERNAL OPERAND_VISIBLE
+
+%type <string> OPERAND_NAME OPERAND_INTERNAL OPERAND_VISIBLE
+
+
+%%
+
+
+operands : /* empty */
+         | operands OPERAND_NAME     { register_syntax_item(syntax, $2, SIT_KEYWORD); }
+         | operands OPERAND_INTERNAL { register_syntax_item(syntax, $2, SIT_INT_OPERAND); }
+         | operands OPERAND_VISIBLE  { register_syntax_item(syntax, $2, SIT_EXT_OPERAND); }
+
+
+%%
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : syntax = structure impliquée dans le processus.              *
+*                msg    = message d'erreur.                                   *
+*                                                                             *
+*  Description : Affiche un message d'erreur suite à l'analyse en échec.      *
+*                                                                             *
+*  Retour      : 0                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int yyerror(asm_syntax *syntax, char *msg)
+{
+	printf("syntax yyerror line %d: %s\n", yyget_lineno(), msg);
+
+	return 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : syntax = structure à constituer à partir de données lues.    *
+*                raw    = données brutes à analyser.                          *
+*                                                                             *
+*  Description : Interprête des données liées à une définition de syntaxe.    *
+*                                                                             *
+*  Retour      : true si l'opération s'est bien déroulée, false sinon.        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool load_syntax_from_raw_line(asm_syntax *syntax, const char *raw)
+{
+    bool result;                            /* Bilan à faire remonter      */
+    YY_BUFFER_STATE state;                  /* Support d'analyse           */
+    int status;                             /* Bilan de l'analyse          */
+
+    state = yy_scan_string(raw);
+
+    status = yyparse(syntax);
+
+    result = (status == 0);
+
+    yy_delete_buffer(state);
+
+    return result;
+
+}
diff --git a/tools/d2c/syntax/manager.c b/tools/d2c/syntax/manager.c
new file mode 100644
index 0000000..ae2a71b
--- /dev/null
+++ b/tools/d2c/syntax/manager.c
@@ -0,0 +1,385 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * manager.c - prise en compte d'une syntaxe du langage d'assemblage
+ *
+ * Copyright (C) 2014 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "manager.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include "../helpers.h"
+
+
+
+/* Propriétés particulières pour les opérandes */
+typedef enum _SyntaxItemFlags
+{
+    SIF_NONE     = (0 << 0),                /* Aucune propriété            */
+    SIF_DECIMAL  = (1 << 0),                /* Affichage en décimal        */
+    SIF_OPTIONAL = (1 << 1)                 /* Absence tolérée             */
+
+} SyntaxItemFlags;
+
+/* Elément défini dans une syntaxe */
+typedef struct _syntax_item
+{
+    char *name;                             /* Désignation humaine         */
+    SyntaxItemType impact;                  /* Portée de l'élément         */
+    SyntaxItemFlags flags;                  /* Propriétés supplémentaires  */
+
+} syntax_item;
+
+/* Syntaxe d'une ligne d'assembleur */
+struct _asm_syntax
+{
+    syntax_item *items;                     /* Eléments de la syntaxe      */
+    size_t items_count;                     /* Nombre de ces éléments      */
+
+};
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée un nouvel indicateur pour l'écriture d'une instruction. *
+*                                                                             *
+*  Retour      : Nouvelle structure prête à emploi.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+asm_syntax *create_asm_syntax(void)
+{
+    asm_syntax *result;                    /* Définition vierge à renvoyer*/
+
+    result = (asm_syntax *)calloc(1, sizeof(asm_syntax));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : syntax = gestionnaire d'un ensemble d'éléments de syntaxe.   *
+*                                                                             *
+*  Description : Supprime de la mémoire un indicateur d'écriture ASM.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void delete_asm_syntax(asm_syntax *syntax)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < syntax->items_count; i++)
+        free(syntax->items[i].name);
+
+    if (syntax->items != NULL)
+        free(syntax->items);
+
+    free(syntax);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : syntax = gestionnaire d'un ensemble d'éléments de syntaxe.   *
+*                name   = désignation de l'opérande dans la spécification.    *
+*                impact = précise la portée effective de l'opérande           *
+*                                                                             *
+*  Description : Enregistre la présence d'un nouvel opérande dans la syntaxe. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void register_syntax_item(asm_syntax *syntax, char *name, SyntaxItemType impact)
+{
+    syntax_item *item;                      /* Nouvelle prise en compte    */
+    size_t len;                             /* Taille du nom fourni        */
+
+    syntax->items = (syntax_item *)realloc(syntax->items, ++syntax->items_count * sizeof(syntax_item));
+
+    item = &syntax->items[syntax->items_count - 1];
+
+    /* Récupération des drapeaux */
+
+    item->flags = SIF_NONE;
+
+    for (len = strlen(name); len > 0; len--)
+        switch (name[0])
+        {
+            case '#':
+                item->flags |= SIF_DECIMAL;
+                memmove(name, name + 1, len);
+                break;
+
+            case '?':
+                item->flags |= SIF_OPTIONAL;
+                memmove(name, name + 1, len);
+                break;
+
+            default:
+                len = 1;
+                break;
+
+        }
+
+    if (impact == SIT_KEYWORD)
+        item->name = name;
+    else
+        item->name = make_string_lower(name);
+
+    item->impact = impact;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : syntax = gestionnaire d'un ensemble d'éléments de syntaxe.   *
+*                bits   = gestionnaire des bits d'encodage.                   *
+*                list   = liste de l'ensemble des fonctions de conversion.    *
+*                                                                             *
+*  Description : Marque les champs de bits effectivement utilisés.            *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool mark_syntax_items(const asm_syntax *syntax, const coding_bits *bits, const conv_list *list)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t i;                               /* Boucle de parcours          */
+    syntax_item *item;                      /* Lien vers un opérande       */
+    conv_func *func;                        /* Fonction de conversion      */
+
+    result = true;
+
+    for (i = 0; i < syntax->items_count && result; i++)
+    {
+        item = &syntax->items[i];
+        if (item->impact == SIT_KEYWORD) continue;
+
+        func = find_named_conv_in_list(list, item->name);
+        if (func == NULL)
+        {
+            fprintf(stderr, "Error: expected conversion for '%s'.\n", item->name);
+            result = false;
+        }
+
+        result = mark_conv_func(func, bits, list);
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : syntax = gestionnaire d'un ensemble d'éléments de syntaxe.   *
+*                fd     = descripteur d'un flux ouvert en écriture.           *
+*                bits   = gestionnaire des bits d'encodage.                   *
+*                list   = liste de l'ensemble des fonctions de conversion.    *
+*                wide   = taille des mots décodés.                            *
+*                                                                             *
+*  Description : Déclare les variables C associées aux opérandes de syntaxe.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool declare_syntax_items(const asm_syntax *syntax, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide)
+{
+    bool result;                            /* Bilan à retourner           */
+    bool has_operand;                       /* Présence d'un opérande      */
+    size_t i;                               /* Boucle de parcours          */
+    syntax_item *item;                      /* Lien vers un opérande       */
+    conv_func *func;                        /* Fonction de conversion      */
+
+    result = true;
+
+    has_operand = false;
+
+    for (i = 0; i < syntax->items_count && result; i++)
+    {
+        item = &syntax->items[i];
+        if (item->impact == SIT_KEYWORD) continue;
+
+        has_operand |= (item->impact == SIT_EXT_OPERAND);
+
+        func = find_named_conv_in_list(list, item->name);
+        if (func == NULL)
+        {
+            fprintf(stderr, "Error: expected conversion for '%s'.\n", item->name);
+            result = false;
+        }
+
+        result &= declare_conv_func(func, fd, bits, list, wide);
+
+    }
+
+    if (has_operand)
+        dprintf(fd, "\t\tGArchOperand *op;\n");
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : syntax = gestionnaire d'un ensemble d'éléments de syntaxe.   *
+*                                                                             *
+*  Description : Fournit si elle existe un nom nouveau pour une instruction.  *
+*                                                                             *
+*  Retour      : Eventuelle chaîne de caractères trouvée ou NULL.             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *get_new_keyword_from_syntax_items(const asm_syntax *syntax)
+{
+    const char *result;                     /* Nom éventuel à renvoyer     */
+
+    result = NULL;
+
+    if (syntax->items_count > 0
+        && syntax->items[0].impact == SIT_KEYWORD)
+    {
+        result = syntax->items[0].name;
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : syntax = gestionnaire d'un ensemble d'éléments de syntaxe.   *
+*                fd     = descripteur d'un flux ouvert en écriture.           *
+*                arch   = architecture visée par l'opération globale.         *
+*                bits   = gestionnaire des bits d'encodage.                   *
+*                list   = liste de l'ensemble des fonctions de conversion.    *
+*                pp     = pré-processeur pour les échanges de chaînes.        *
+*                exit   = exprime le besoin d'une voie de sortie. [OUT]       *
+*                                                                             *
+*  Description : Définit les variables C associées aux opérandes de syntaxe.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool define_syntax_items(const asm_syntax *syntax, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp, bool *exit)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t i;                               /* Boucle de parcours          */
+    syntax_item *item;                      /* Lien vers un opérande       */
+    conv_func *func;                        /* Fonction de conversion      */
+    bool internal;                          /* Usage interne ou non ?      */
+
+    result = true;
+
+    for (i = 0; i < syntax->items_count && result; i++)
+    {
+        item = &syntax->items[i];
+
+        switch (item->impact)
+        {
+            case SIT_KEYWORD:
+
+                if (i > 0)
+                    dprintf(fd, "\t\tg_arch_instruction_append_suffix(instr, \"%s\");\n", item->name);
+                else
+                    continue;
+
+                break;
+
+            case SIT_INT_OPERAND:
+            case SIT_EXT_OPERAND:
+
+                internal = (item->impact == SIT_INT_OPERAND);
+
+                func = find_named_conv_in_list(list, item->name);
+                if (func == NULL)
+                {
+                    fprintf(stderr, "Error: expected conversion for '%s'.\n", item->name);
+                    result = false;
+                }
+
+                /* Appel proprement dit */
+
+                result &= define_conv_func(func, true, internal, fd, arch, bits, list, pp);
+                if (!result) break;
+
+                /* Raccordement : propriété ou opérande ? */
+
+                if (internal)
+                    dprintf(fd, "\t\t\tgoto bad_exit;\n");
+
+                else
+                {
+                    dprintf(fd, "\t\tif (op == NULL) goto bad_exit;\n");
+
+                    dprintf(fd, "\n");
+
+                    if (item->flags & SIF_DECIMAL)
+                        dprintf(fd, "\t\tg_imm_operand_set_default_display(G_IMM_OPERAND(op), IOD_DEC);\n");
+
+                    dprintf(fd, "\t\tg_arch_instruction_attach_extra_operand(instr, op);\n");
+
+                }
+
+                *exit = true;
+                break;
+
+        }
+
+        dprintf(fd, "\n");
+
+    }
+
+    return result;
+
+}
diff --git a/tools/d2c/syntax/manager.h b/tools/d2c/syntax/manager.h
new file mode 100644
index 0000000..1ae1a24
--- /dev/null
+++ b/tools/d2c/syntax/manager.h
@@ -0,0 +1,73 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * manager.h - prototypes pour la prise en compte d'une syntaxe du langage d'assemblage
+ *
+ * Copyright (C) 2014 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _TOOLS_D2C_SYNTAX_MANAGER_H
+#define _TOOLS_D2C_SYNTAX_MANAGER_H
+
+
+#include <stdbool.h>
+
+
+#include "../pproc.h"
+#include "../bits/manager.h"
+#include "../conv/manager.h"
+
+
+
+/* Type d'éléments de syntaxe */
+typedef enum _SyntaxItemType
+{
+    SIT_KEYWORD,                            /* Elément de l'instruction    */
+    SIT_INT_OPERAND,                        /* Propriété d'architecture    */
+    SIT_EXT_OPERAND                         /* Opérande généraliste        */
+
+} SyntaxItemType;
+
+/* Syntaxe d'une ligne d'assembleur */
+typedef struct _asm_syntax asm_syntax;
+
+
+/* Crée un nouvel indicateur pour l'écriture d'une instruction. */
+asm_syntax *create_asm_syntax(void);
+
+/* Supprime de la mémoire un indicateur d'écriture ASM. */
+void delete_asm_syntax(asm_syntax *);
+
+/* Enregistre la présence d'un nouvel opérande dans la syntaxe. */
+void register_syntax_item(asm_syntax *, char *, SyntaxItemType);
+
+/* Marque les champs de bits effectivement utilisés. */
+bool mark_syntax_items(const asm_syntax *, const coding_bits *, const conv_list *);
+
+/* Déclare les variables C associées aux opérandes de syntaxe. */
+bool declare_syntax_items(const asm_syntax *, int, const coding_bits *, const conv_list *, unsigned int);
+
+/* Fournit si elle existe un nom nouveau pour une instruction. */
+const char *get_new_keyword_from_syntax_items(const asm_syntax *);
+
+/* Définit les variables C associées aux opérandes de syntaxe. */
+bool define_syntax_items(const asm_syntax *, int, const char *, const coding_bits *, const conv_list *, const pre_processor *, bool *);
+
+
+
+#endif  /* _TOOLS_D2C_SYNTAX_MANAGER_H */
diff --git a/tools/d2c/syntax/tokens.l b/tools/d2c/syntax/tokens.l
new file mode 100644
index 0000000..ab1b0f3
--- /dev/null
+++ b/tools/d2c/syntax/tokens.l
@@ -0,0 +1,39 @@
+
+%top {
+
+#include "grammar.h"
+
+}
+
+
+%option noyywrap
+%option nounput
+%option noinput
+%option yylineno
+%option stack
+%option noyy_top_state
+
+%x named
+%x internal
+%x visible
+
+
+%%
+
+
+" "                     { }
+
+"\""                    { yy_push_state(named); }
+<named>[^ \"]+          { yylvalp->string = strdup(yytext); return OPERAND_NAME; }
+<named>"\""             { yy_pop_state(); }
+
+"{"                     { yy_push_state(internal); }
+<internal>[^ }]+        { yylvalp->string = strdup(yytext); return OPERAND_INTERNAL; }
+<internal>"}"           { yy_pop_state(); }
+
+"<"                     { yy_push_state (visible); }
+<visible>[^ >]+         { yylvalp->string = strdup(yytext); return OPERAND_VISIBLE; }
+<visible>">"            { yy_pop_state(); }
+
+
+%%
diff --git a/tools/d2c/tokens.l b/tools/d2c/tokens.l
new file mode 100644
index 0000000..e48d079
--- /dev/null
+++ b/tools/d2c/tokens.l
@@ -0,0 +1,132 @@
+
+%top {
+
+#include "grammar.h"
+
+}
+
+
+
+%{
+
+    //typedef struct _rented_coder rented_coder;
+
+
+//#include "d2c-d2c_gram.h"
+
+#include <ctype.h>
+#include <string.h>
+
+
+#include "manual.h"
+
+
+
+%}
+
+%option noyywrap
+%option nounput
+ //%option noinput
+%option yylineno
+%option stack
+%option noyy_top_state
+
+ //%option reentrant
+ //%option bison-bridge
+
+/* %option bison-bridge */
+/* %option bison-locations */
+/* %option ecs */
+/* %option nodefault */
+/* %option noyywrap */
+/* %option reentrant */
+
+
+%x comments
+
+%x ins_name try_details ins_details
+%x encoding encoding_type encoding_content
+
+%x encoding_bits encoding_bits_size
+
+%x raw_line
+
+
+
+%%
+
+
+[ \t\n]+                            { }
+
+"/*"                                { BEGIN(comments); }
+<comments>"*/"                      { BEGIN(INITIAL); }
+<comments>[^*\n]                    { }
+<comments>"Copyright"[^\n]*         { yylvalp->string = strdup(yytext); return COPYRIGHT; }
+<comments>"*"                       { }
+<comments>"\n"                      { }
+
+
+"@title"                            { BEGIN(ins_name); return TITLE; }
+
+<ins_name>[ ][A-Za-z-]+             { yylvalp->string = strdup(yytext + 1); BEGIN(try_details); return INS_NAME; }
+<try_details>[ ,/]                  { BEGIN(ins_details); }
+<try_details>[\n]                   { BEGIN(INITIAL); }
+
+<ins_details>[^\n]*                 { yylvalp->cstring = yytext; return INS_DETAILS; }
+<ins_details>[\n]                   { BEGIN(INITIAL); }
+
+
+
+"@encoding"                         { BEGIN(encoding); return ENCODING; }
+
+<encoding>[ ]                       { }
+<encoding>"("                       { BEGIN(encoding_type); }
+
+<encoding_type>[A-Za-z]             { yylvalp->string = strdup(yytext); return TYPE; }
+<encoding_type>[0-9]+               { yylvalp->integer = atoi(yytext); return NUMBER; }
+<encoding_type>")"                  { BEGIN(encoding); }
+
+<encoding>"{"                       { BEGIN(encoding_content); }
+<encoding_content>[ \t\n]+          { }
+<encoding_content>"}"               { BEGIN(INITIAL); }
+
+
+
+<encoding_content>"@half "          { yy_push_state(raw_line); return HALF; }
+<encoding_content>"@word "          { yy_push_state(raw_line); return WORD; }
+
+
+<raw_line>[^\n]+                    { yylvalp->cstring = yytext; return RAW_LINE; }
+<raw_line>"\n"                      { yy_pop_state(); }
+
+
+
+
+<encoding_content>"@syntax "        { yy_push_state(raw_line); return SYNTAX; }
+
+
+
+
+
+<encoding_content>"@conv"           { return CONV; }
+
+
+
+
+<encoding_content>"{" {
+    read_block(temp);
+    yylvalp->cstring = temp; return RAW_BLOCK;
+ }
+
+
+
+
+
+
+
+<encoding_content>"@hooks"          { return HOOKS; }
+
+<encoding_content>"@rules"          { return RULES; }
+
+
+%%
-- 
cgit v0.11.2-87-g4458