summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Worth <cworth@cworth.org>2010-05-10 16:16:06 -0700
committerCarl Worth <cworth@cworth.org>2010-05-10 16:16:06 -0700
commit0b27b5f05191f07ed31e65ff07e5233672f3c33a (patch)
tree84c63c12942e748378d73ef734021f788f4cd569
parent725c17a9266c1141508da623c8781412853b70e4 (diff)
Implment #define
By using the recently-imported hash_table implementation.
-rw-r--r--glcpp-lex.l23
-rw-r--r--glcpp-parse.y49
-rw-r--r--glcpp.c10
-rw-r--r--glcpp.h21
4 files changed, 87 insertions, 16 deletions
diff --git a/glcpp-lex.l b/glcpp-lex.l
index 747e24056f..a220fef76b 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; }
+
+<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; }
%%
diff --git a/glcpp-parse.y b/glcpp-parse.y
index a2d1094253..89dc46497f 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 eefac74be9..d6c89df2f9 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 485387b8a5..5278e1b971 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