user8786494
user8786494

Reputation: 21

Flex not compiling Lexical Analyser - error with macro

I am having a problem with my lexical analyser written in flex. When I try to compile it there is no exe file created and I get a lot of errors. The following is the flex file:

%{
#ifdef PRINT
#define TOKEN(t) printf("Token: " #t "\n");
#else
#define TOKEN(t) return(t);
#endif
%}

delim       [ \t\n]
ws          {delim}+
digit       [0-9]
id          {character}({character}|{digit})*
number      {digit}+
character   [A-Za-z]
%%
{ws}            ; /* Do Nothing */


":"             TOKEN(COLON);
";"             TOKEN(SEMICOLON);
","             TOKEN(COMMA);
"("             TOKEN(BRA);
")"             TOKEN(CKET);
"."             TOKEN(DOT);
"'"             TOKEN(APOS);

"="             TOKEN(EQUALS);
"<"             TOKEN(LESSTHAN);
">"             TOKEN(GREATERTHAN);

"+"             TOKEN(PLUS);
"-"             TOKEN(SUBTRACT);
"*"             TOKEN(MULTIPLY);
"/"             TOKEN(DIVIDE);

{id}            TOKEN(ID);

{number}        TOKEN(NUMBER);

'{character}'   TOKEN(CHARACTER_CONSTANT);

%%

These are the errors I receive:

spl.l: In function 'yylex':

spl.l:19:7: error: 'COLON' undeclared (first use in this function)
 ":"    TOKEN(COLON);
       ^

spl.l:5:25: note: in definition of macro 'TOKEN'
 #define TOKEN(t) return(t);
                         ^

spl.l:19:7: note: each undeclared identifier is reported only once for each function it appears in
 ":"    TOKEN(COLON);
       ^

spl.l:5:25: note: in definition of macro 'TOKEN'
 #define TOKEN(t) return(t);
                         ^

spl.l:20:7: error: 'SEMICOLON' undeclared (first use in this function)
 ";"    TOKEN(SEMICOLON);
       ^

spl.l:5:25: note: in definition of macro 'TOKEN'
 #define TOKEN(t) return(t);

And the commands I am using to compile are:

flex a.l
gcc -o newlex.exe lex.yy.c -lfl

Can anyone see where I may be going wrong?

Upvotes: 1

Views: 227

Answers (1)

Ctx
Ctx

Reputation: 18410

You have to define the tokens first. The definitions (i.e. ids) for COLON, SEMICOLON, etc. pp. are not generated by flex. You could define it in an enum at the top of your lexer file:

%{
#ifdef PRINT
#define TOKEN(t) printf("Token: " #t "\n");
#else
#define TOKEN(t) return(t);
#endif  

enum { COLON = 257, SEMICOLON, COMMA, BRA, CKET, DOT, APOS, EQUALS,
       LESSTHAN, GREATERTHAN, PLUS, SUBTRACT, MULTIPLY, DIVIDE,
       ID, NUMBER, CHARACTER_CONSTANT };
%}

I suggest ids > 257 here to be able to also directly return ascii character codes from the lexer for further processing. Usually, however, the token names are also used in a parser file for yacc/bison, which generates a header file (default name is y.tab.h) for inclusion in your lexer, which contains generated ids for those tokens which also match the parser functions.

Upvotes: 2

Related Questions