diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2016-01-28 23:32:25 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2016-01-28 23:32:25 (GMT) | 
| commit | 16e0fd9d89ef433848678dfc8dd20426844a2868 (patch) | |
| tree | 79075ae02c133cea21ffb555b1086aae833b3aac /tools/d2c/conv | |
| parent | 66c99d59d6a6d533de0bb65488de8243213bcdea (diff) | |
Cleaned, rewritten and improved the whole code of the compiler.
Diffstat (limited to 'tools/d2c/conv')
| -rw-r--r-- | tools/d2c/conv/Makefile.am | 31 | ||||
| -rw-r--r-- | tools/d2c/conv/decl.h | 37 | ||||
| -rw-r--r-- | tools/d2c/conv/grammar.y | 130 | ||||
| -rw-r--r-- | tools/d2c/conv/manager.c | 518 | ||||
| -rw-r--r-- | tools/d2c/conv/manager.h | 94 | ||||
| -rw-r--r-- | tools/d2c/conv/tokens.l | 32 | 
6 files changed, 842 insertions, 0 deletions
| 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(); } + + +%% | 
