views:

104

answers:

2

I'm totally new to flex.

I'm getting a build error when using flex. That is, I've generated a .c file using flex, and, when running it, am getting this error:

1>lextest.obj : error LNK2001: unresolved external symbol "int __cdecl isatty(int)" (?isatty@@YAHH@Z)
1>C:\...\lextest.exe : fatal error LNK1120: 1 unresolved externals

here is the lex file I'm using (grabbed from here):

/*** Definition section ***/

%{
/* C code to be copied verbatim */
#include <stdio.h>
%}

/* This tells flex to read only one input file */
%option noyywrap


%%
    /*** Rules section ***/

    /* [0-9]+ matches a string of one or more digits */
[0-9]+  {
            /* yytext is a string containing the matched text. */
            printf("Saw an integer: %s\n", yytext);
        }

.       {   /* Ignore all other characters. */   }

%%
/*** C Code section ***/

int main(void)
{
    /* Call the lexer, then quit. */
    yylex();
    return 0;
}

As well, why do I have to put a 'main' function in the lex syntax code? What I'd like is to be able to call yylex(); from another c file.

+2  A: 

Q1 Link Error

It looks a bit as if something is confused about the isatty() function. It doesn't show in the code you show - but it might be referenced in the code generated by flex. If so, it appears that you are compiling with a C++ compiler, and the isatty() function is being treated as a function with C++ linkage and is not being found - it is normally a function with C linkage and would need to be declared with 'extern "C" int isatty(int);' in C++ code.

To resolve, track down whether isatty() appears in the generated C. If so, also track down where it is declared (the POSIX standard header for it is <unistd.h>).

Q2 Main

You do not have to put the main program in the file with the lexer. Indeed, you often won't do that, or the main program in there will simply be a dummy used to test the lexer in isolation (and only compiled into the code conditionally - inside #ifdef TEST / #endif or equivalent).

What makes you think that you have to do it?

Jonathan Leffler
+1 - Thanks! I added the extern code as c code in the flex file, and it worked great. My only other problem is this: Every time i generate a c file, the following is included as one of the lines: "#include <unistd.h>", and I want it to not do that. Any ideas?
Cam
(couldn't edit anymore) To answer your last question, the reason I'm saying I have to do that, is if I try calling yylex from my normal main(), it simply says the function can't be found.
Cam
@incrediman: It depends on where the flex came from...there's sometimes a template file that flex copies into its output; sometimes, the contents of that file is built into flex. If there's a file, you can hack it - beware of upgrades. If the file is compiled into the flex binary, you'll need to build your own, or report the bug, or compile the flex code with a C compiler (and then you can link with the C++ compiler - but make sure that you specify in the rest of your code that `yylex()` has C linkage.
Jonathan Leffler
@incrediman: For the main() program stuff - again, it is C++ vs C linkage, I think. I already intimated that in the previous comment.
Jonathan Leffler
@Jnathon Thanks! This has been really helpful! And yeah (@ your last comment) - you're right! Sorry about that :)
Cam
@incrediman: you were typing up comments at the same time I was - the 'already intimated' bit simply meant that I'd partially covered it, but only while you were typing up your next comment/question.
Jonathan Leffler
A: 

The link error looks like you're trying to use a non-windows-native version of flex on windows, and its not working properly. If you use the version of flex that comes with cygwin, you need to compile and link the program with cygwin's compiler and linker.

Chris Dodd