By using the recently-imported hash_table implementation.
%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; }
%%
#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);
+}
;
%%
{
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);
+}
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;
}
#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);
/* Generated by glcpp-parse.y to glcpp-parse.c */
int
-yyparse (void *scanner);
+yyparse (glcpp_parser_t *parser);
#endif