[GoLUG] [parse] My studies with O'Reilly's book on Flex and Bison
Steve Litt
slitt at troubleshooters.com
Thu Nov 23 20:23:46 EST 2023
David Billsbrough said on Thu, 23 Nov 2023 05:17:45 +0000
>Original Message:
>
> Once upon a time, Steve Litt <slitt at trou.....com> wrote:
>
>> Hi all,
>
>> After hitting all sorts of dead ends, I decided to read "flex &
>> bison" by John Levine, published by O'Reilly. Unfortunately,
[snip]
>
>I tried the fb1-1.l example and got it to output:
>
>I did this under my VPS running Ubuntu:
I finally got fb1-1.l running properly. Some of my problems were my
mistakes. Others of my problems were my efforts to kill all warnings
for gcc -Wall , which I finally succeeded with. A big problem was the
-lfl on gcc, which caused 'multiple definition of "main"'.
So I did the following with my revised version of fb1-1.l, which I
called wc.l:
flex wc.l
gcc -Wall lex.yy.c
cat test.txt | ./a.out
Yeah, I don't wanna hear about useless use of cat, I like it that way.
The wc.l code that compiles with no errors and no warnings follows:
====================================================================
/* Almost just like Unix wc
Adapted from program fb1-1.l
in John Levine's "Flex & Bison"
book at https://www.oreilly.com/
library/view/flex-bison/9780596805418/
To compile and run, assuming this file
is called wc.l, perform the following
three commands, where test.txt is a
sample text file containing words
separated by spaces and paragraphs
separated by blank lines:
flex wc.l
gcc -Wall lex.yy.c
cat test.txt | ./a.out
*/
%{
/* Global definitions/declarations occur
here in the declarations section.
*/
int chars = 0;
int words = 0;
int lines = 0;
/* Following definition/declaration
of yywrap() adds a necessary
definition in order not to have
a "not found" error. The
"return 1;" is a kludge to prevent
a "control at end of void function
warning. Note that if you change
the 1 to 0, your program fails.
This kludge might not work everywhere,
so beware!
*/
int yywrap(void){return 1;};
%}
/* The three rules in the rules section that
follows can be in any order. I don't know
why, or by what magic the any char (dot)
code is not triggered every time. If you
know, please explain it to me.
*/
%%
. { chars++; }
\n { chars++; lines++;}
[a-zA-Z]+ { words++; chars += strlen(yytext); }
%%
int main(int argc, char **argv)
{
yylex();
printf("%8d%8d%8d\n", lines, words, chars);
if(0) { /* never happens */
input(); /* kill warning */
yyunput(1, "Just to kill warning");
}
return 0;
}
====================================================================
If anybody, with any OS or distro, exactly copies the preceding code to
wc.l and uses flex and gcc to build, as documented at the program's
top, and gets an error or warning, please let me know. By the way, this
program's definition of separators is slightly different from those of
wc, so you won't get exactly the same results, but that's OK, this is
meant to be a learning stepping stone.
Thanks,
SteveT
Steve Litt
Autumn 2023 featured book: Rapid Learning for the 21st Century
http://www.troubleshooters.com/rl21
More information about the GoLUG
mailing list