From 0b27b5f05191f07ed31e65ff07e5233672f3c33a Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 10 May 2010 16:16:06 -0700 Subject: [PATCH] Implment #define By using the recently-imported hash_table implementation. --- glcpp-lex.l | 23 +++++++++++++++++++---- glcpp-parse.y | 49 +++++++++++++++++++++++++++++++++++++++++++------ glcpp.c | 10 ++++++---- glcpp.h | 21 +++++++++++++++++++-- 4 files changed, 87 insertions(+), 16 deletions(-) diff --git a/glcpp-lex.l b/glcpp-lex.l index 747e240..a220fef 100644 --- a/glcpp-lex.l +++ b/glcpp-lex.l @@ -31,12 +31,27 @@ %option reentrant noyywrap +%x ST_DEFINE +%x ST_DEFVAL + +SPACE [[:space:]] +NONSPACE [^[:space:]] +NOTNEWLINE [^\n] +HSPACE [ \t] +HASH ^{HSPACE}*# +IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]* +DEFVAL {NONSPACE}{NOTNEWLINE}* %% - /* Silently eat all whitespace. */ -[[:space:]]+ +{HASH}define { BEGIN ST_DEFINE; return DEFINE; } + +{HSPACE}+ +{IDENTIFIER} { BEGIN ST_DEFVAL; yylval = strdup (yytext); return IDENTIFIER; } + +{SPACE}+ +{DEFVAL} { BEGIN INITIAL; yylval = strdup (yytext); return DEFVAL; } - /* Any non-whitespace is a token. */ -[^[:space:]]+ { return TOKEN; } + /* Anything we don't specifically recognize is a stream of tokens */ +{NONSPACE}+ { yylval = strdup (yytext); return TOKEN; } %% diff --git a/glcpp-parse.y b/glcpp-parse.y index a2d1094..89dc464 100644 --- a/glcpp-parse.y +++ b/glcpp-parse.y @@ -27,30 +27,46 @@ #include "glcpp.h" -#define YYSTYPE int +#define YYLEX_PARAM parser->scanner void yyerror (void *scanner, const char *error); %} -%parse-param {void *scanner} +%parse-param {glcpp_parser_t *parser} %lex-param {void *scanner} +%token DEFINE +%token DEFVAL +%token IDENTIFIER %token TOKEN %% input: /* empty */ - | tokens + | content ; +content: token + | directive + | content token + | content directive +; -tokens: token - | tokens token +directive: DEFINE IDENTIFIER DEFVAL { + hash_table_insert (parser->defines, $3, $2); +} ; -token: TOKEN +token: TOKEN { + char *value = hash_table_find (parser->defines, $1); + if (value) + printf ("%s", value); + else + printf ("%s", $1); + free ($1); +} ; %% @@ -60,3 +76,24 @@ yyerror (void *scanner, const char *error) { fprintf (stderr, "Parse error: %s\n", error); } + +void +glcpp_parser_init (glcpp_parser_t *parser) +{ + yylex_init (&parser->scanner); + parser->defines = hash_table_ctor (32, hash_table_string_hash, + hash_table_string_compare); +} + +int +glcpp_parser_parse (glcpp_parser_t *parser) +{ + return yyparse (parser); +} + +void +glcpp_parser_fini (glcpp_parser_t *parser) +{ + yylex_destroy (parser->scanner); + hash_table_dtor (parser->defines); +} diff --git a/glcpp.c b/glcpp.c index eefac74..d6c89df 100644 --- a/glcpp.c +++ b/glcpp.c @@ -26,12 +26,14 @@ int main (void) { + glcpp_parser_t parser; int ret; - void *scanner; - yylex_init (&scanner); - ret = yyparse (scanner); - yylex_destroy (scanner); + glcpp_parser_init (&parser); + + ret = glcpp_parser_parse (&parser); + + glcpp_parser_fini (&parser); return ret; } diff --git a/glcpp.h b/glcpp.h index 485387b..5278e1b 100644 --- a/glcpp.h +++ b/glcpp.h @@ -24,10 +24,27 @@ #ifndef GLCPP_H #define GLCPP_H -/* Generated by glcpp-lex.l to glcpp-lex.c */ +#include "hash_table.h" +#define YYSTYPE char * #define yyscan_t void* +typedef struct { + yyscan_t scanner; + struct hash_table *defines; +} glcpp_parser_t; + +void +glcpp_parser_init (glcpp_parser_t *parser); + +int +glcpp_parser_parse (glcpp_parser_t *parser); + +void +glcpp_parser_fini (glcpp_parser_t *parser); + +/* Generated by glcpp-lex.l to glcpp-lex.c */ + int yylex_init (yyscan_t *scanner); @@ -40,6 +57,6 @@ yylex_destroy (yyscan_t scanner); /* Generated by glcpp-parse.y to glcpp-parse.c */ int -yyparse (void *scanner); +yyparse (glcpp_parser_t *parser); #endif -- 2.7.4