Implment #define

By using the recently-imported hash_table implementation.
This commit is contained in:
Carl Worth 2010-05-10 16:16:06 -07:00
parent 725c17a926
commit 0b27b5f051
4 changed files with 88 additions and 17 deletions

View file

@ -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; }
/* Any non-whitespace is a token. */
[^[:space:]]+ { return TOKEN; }
<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; }
/* Anything we don't specifically recognize is a stream of tokens */
{NONSPACE}+ { yylval = strdup (yytext); return TOKEN; }
%%

View file

@ -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
;
tokens: token
| tokens token
content: token
| directive
| content token
| content directive
;
token: TOKEN
directive: DEFINE IDENTIFIER DEFVAL {
hash_table_insert (parser->defines, $3, $2);
}
;
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);
}

10
glcpp.c
View file

@ -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;
}

21
glcpp.h
View file

@ -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