1
votes

I am currently working through sample code from the O'Reilly press book entitled "Flex and Bison". I am using the GNU C compiler for Windows with Flex and Bison binary install for Windows which is launched using gcc rather than the Linux cc command. The problem is that the code if copied directly from the book does not compile and I have had to hack it a bit to get it to work.

Example from book

 Example 1-1. Word count fb1-1.l

/* just like Unix wc */

%{

int chars = 0;

int words = 0;

int lines = 0;

%}

%%

[a-zA-Z]+ { words++; chars += strlen(yytext); }

\n { chars++; lines++; }

. { chars++; }

%%
main(int argc, char **argv)

{

yylex();

printf("%8d%8d%8d\n", lines, words, chars);

}

I compiled the code in the flowing way using Windows command line: flex file.l gcc lex.yy.c -o a.exe

It crashed stating yywrap() was not found. I added that and then it worked but did not complete the printf in the main function as it just hung waiting for more input!

Here is my solution that works but feels like a hack and that I am not in full understanding of the process.

    /* just like Unix wc */

%{

    *#include <string.h>*

    int chars = 0;

    int words = 0;

    int lines = 0;

%}

%%

[a-zA-Z]+   { words++; chars += strlen(yytext); }

\n          { chars++; lines++; }

*"."         { return ;}*

.           { chars++; }


%%

*int yywrap(void)
{
    return 1;
}*

int main(void)

{
    yylex();

    printf("num lines is %8d, num words is %8d, num chars is %8d\n", lines, words, chars);

    return 0;


}

I had to add a new rule to return out of yylex() which was not in the book, add yywrap()- not really knowing why and add string.h which was not present!. My main question is are there significant differences between flex for Windows and Unix and is it possible to run the original code with my gcc compiler and gnu flex without the said hacks?

1

1 Answers

0
votes

I do not understand what have you achieved with this:

#include <string.h>

"." { return; }

But what I know for sure is that if you are running FLEX without specified input file you have to mark the end of input. Otherwise FLEX will wait for input. What I would suggest:

%{
#include <stdio.h>
int chars = 0;
int words = 0;
int lines = 0;
%}
WORD        [a-zA-Z]+
%%
{WORD}  {
            words++;
            chars += strlen(yytext);
        }
\n      {
            lines++;
            /* chars++; why this? there was no columns here - it's a new line */
        }
\s      {
            /* count the spaces */
            chars++;
        }
\t      {
            /* count the tabs */
            chars += 4 /* or 8 */;
        }
.       {
            printf("Error (unknown symbol):\t%c\n", yytext[0]);
            chars++;
        }
%%
int main()
{
    /* iterate until end of input and even if errors - continue */
    while(yylex()){ }
    printf("lines:\t%8d\nwords:\t%8d\nchars:\t%8d\n", lines, words, chars);
    return 0;
}

Build with:

flex input.l

output will be lex.yy.c Then build:

gcc -o scanner.exe lex.yy.c -lfl

Create a txt file with input. Run following:

scanner.exe <in.txt>out.txt

Less sign means redirect input from file in.txt while greater sign means redirect output to out.txt Cause file has EOF at the end of file FLEX will properly stop.