#include "glcpp.h"
#include "glcpp-parse.h"
+
+/* Yes, a macro with a return statement in it is evil. But surely no
+ * more evil than all the code generation happening with flex in the
+ * first place. */
+#define LEXIFY_IDENTIFIER do { \
+ yylval.str = xtalloc_strdup (yyextra, yytext); \
+ switch (glcpp_parser_macro_type (yyextra, yylval.str)) \
+ { \
+ case MACRO_TYPE_UNDEFINED: \
+ return IDENTIFIER; \
+ break; \
+ case MACRO_TYPE_OBJECT: \
+ return OBJ_MACRO; \
+ break; \
+ case MACRO_TYPE_FUNCTION: \
+ return FUNC_MACRO; \
+ break; \
+ } \
+ } while (0)
+
%}
%option reentrant noyywrap
%option extra-type="glcpp_parser_t *"
%x ST_DEFINE
+%x ST_DEFVAL_START
%x ST_DEFVAL
+%x ST_UNDEF
+%x ST_UNDEF_END
SPACE [[:space:]]
NONSPACE [^[:space:]]
%%
{HASH}undef{HSPACE}* {
+ BEGIN ST_UNDEF;
return UNDEF;
}
+<ST_UNDEF>{IDENTIFIER} {
+ BEGIN ST_UNDEF_END;
+ LEXIFY_IDENTIFIER;
+}
+
+<ST_UNDEF_END>\n {
+ BEGIN INITIAL;
+ return NEWLINE;
+}
+
/* We use the ST_DEFINE and ST_DEFVAL states so that we can
* pass a space token, (yes, a token for whitespace!), since
* the preprocessor specification requires distinguishing
}
<ST_DEFINE>{IDENTIFIER} {
- BEGIN ST_DEFVAL;
+ BEGIN ST_DEFVAL_START;
yylval.str = xtalloc_strdup (yyextra, yytext);
return IDENTIFIER;
}
-<ST_DEFVAL>\n {
+<ST_DEFVAL_START>\n {
BEGIN INITIAL;
return NEWLINE;
}
-<ST_DEFVAL>{HSPACE}+ {
- BEGIN INITIAL;
+<ST_DEFVAL_START>{HSPACE}+ {
+ BEGIN ST_DEFVAL;
return SPACE;
}
-<ST_DEFVAL>"(" {
- BEGIN INITIAL;
+<ST_DEFVAL_START>"(" {
+ BEGIN ST_DEFVAL;
return '(';
}
-{IDENTIFIER} {
+<ST_DEFVAL>{IDENTIFIER} {
+ LEXIFY_IDENTIFIER;
+}
+
+<ST_DEFVAL>[(),] {
+ return yytext[0];
+}
+
+<ST_DEFVAL>{TOKEN} {
yylval.str = xtalloc_strdup (yyextra, yytext);
- switch (glcpp_parser_macro_type (yyextra, yylval.str))
- {
- case MACRO_TYPE_UNDEFINED:
- return IDENTIFIER;
- break;
- case MACRO_TYPE_OBJECT:
- return OBJ_MACRO;
- break;
- case MACRO_TYPE_FUNCTION:
- return FUNC_MACRO;
- break;
- }
+ return TOKEN;
+}
+
+<ST_DEFVAL>\n {
+ BEGIN INITIAL;
+ return NEWLINE;
+}
+
+<ST_DEFVAL>{HSPACE}+
+
+{IDENTIFIER} {
+ LEXIFY_IDENTIFIER;
}
[(),] {
}
\n {
- return NEWLINE;
+ printf ("\n");
}
{HSPACE}+
../glcpp < $test > $test.out
gcc -E $test -o $test.gcc
grep -v '^#' < $test.gcc > $test.expected
- diff -w -u $test.expected $test.out
+ diff -B -w -u $test.expected $test.out
done