Implment #define
authorCarl Worth <cworth@cworth.org>
Mon, 10 May 2010 23:16:06 +0000 (16:16 -0700)
committerCarl Worth <cworth@cworth.org>
Mon, 10 May 2010 23:16:06 +0000 (16:16 -0700)
By using the recently-imported hash_table implementation.

glcpp-lex.l
glcpp-parse.y
glcpp.c
glcpp.h

index 747e240..a220fef 100644 (file)
 
 %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; }
+
+<ST_DEFINE>{HSPACE}+
+<ST_DEFINE>{IDENTIFIER}        { BEGIN ST_DEFVAL; yylval = strdup (yytext); return IDENTIFIER; }
+
+<ST_DEFVAL>{SPACE}+
+<ST_DEFVAL>{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; }
 
 %%
index a2d1094..89dc464 100644 (file)
 
 #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 (file)
--- a/glcpp.c
+++ b/glcpp.c
 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 (file)
--- a/glcpp.h
+++ b/glcpp.h
 #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