flex/bison config file parser

Matthias Andree matthias.andree at gmx.de
Sat Mar 1 16:11:49 CET 2003


Hi,

I have some stuff to let bison and flex build our parser, all that's
left for us is intergrate. Do we want to go that way and depend on bison
at packaging time and ship the ready-made parser_config.tab.[hc] just as
we ship ready-made parsers' c code (the lexer*.c stuff)?

Do we want to keep our current ad-hoc parser?

If you want to try that code, you'll need bison or yacc in addition to
the tools you usually need to build bogofilter from CVS.

To compile:

flex lexer_config.l

bison -d parser_config.y
# alternative: yacc -d -b parser_config parser_config.y

gcc -g -O -DYYDEBUG=1 -o parser_config \
    parser_config.tab.c lex.lexer_config_.c -I. xmalloc.o xmem_error.o

To try:

./parser_config <../bogofilter.cf.example

-- 
Matthias Andree
-------------- next part --------------
%{
/* C declarations */
#include <stdio.h>
#include <stdlib.h>
#include "system.h"

#define yylex lexer_config_lex
#include "parser_config.tab.h"

extern int lexer_config_lex(void);
extern void yyerror(const char *);
extern bool process_config_parameter(const char *arg, const char *val);
%}

%union {
    char *s;
    bool b;
}

/* BISON DECLS */
%token <s> FLOAT
%token <s> INTEGER
%token <s> STRING OPTION
%token <b> COMMENT
%token ASSIGN OPTION JUNK
%type <b> lines line file

%%
/* GRAMMAR RULES */
file	: /* empty */ { $$ = true; }
	| lines
	;

lines	: line
	| lines line { $$ = $1 && $2 ; }
	;

line	: OPTION ASSIGN INTEGER { $$ = process_config_parameter($1, $3); }
	| OPTION ASSIGN FLOAT   { $$ = process_config_parameter($1, $3); }
	| OPTION ASSIGN STRING  { $$ = process_config_parameter($1, $3); }
	;

%%

/* C code */

bool process_config_parameter(const char *arg, const char *val)
{
    printf("%s <- %s\n", arg, val);
    return true;
}

int main(int argc, char **argv) {
    if(argc >= 2) yydebug = atoi(argv[1]);
    yyparse();
    exit(0);
}

void yyerror(const char *s) {
    fprintf(stderr, "parse error: %s\n", s);
}
-------------- next part --------------
%{
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>

#include "config.h"
#include "system.h"
#include "xmalloc.h"

#include "parser_config.tab.h"

static char *duptok(void);

%}

%option align nounput noyywrap noreject 8bit caseless
%option prefix="lexer_config_"

OPTION		[0-9a-zA-Z_]+
QSTRING		\"[^\n]*\"
USTRING		[^#"\n=]+
STRING		({USTRING})|({QSTRING})
COMMENT		#.*$
ASSIGN		[[:space:]]*=[[:space:]]*

%%

{OPTION}/{ASSIGN}	{ yylval.s = duptok(); return OPTION; }
{COMMENT}		;
{ASSIGN}		return ASSIGN;
{STRING}		{ yylval.s = duptok(); return STRING; }
[[:space:][:cntrl:]]	;
.			return JUNK;

%%

static char *duptok(void) {
    int cut;
    char *x;

    cut = yytext[0] == '"' && yytext[yyleng-1] == '"';
    x = xmalloc(yyleng-cut*2+1);
    memcpy(x, yytext + cut, yyleng-cut*2);
    x[yyleng-cut*2] = 0;
    return x;
}

/*
 * The following sets edit modes for GNU EMACS
 * Local Variables:
 * mode:c
 * End:
 */



More information about the bogofilter-dev mailing list