Suppress "yyunput defined but not used"
To suppress the warning message "yyunput defined but not used" when compiling the flex output with gcc -Wall, use a line
%option nounput
Make flex generate line numbers
%option yylineno
Make flex create a header file declaring yylex
flex --header-file=my.lex.h my.l
Change the yy prefix to something else
%option prefix="myprefix_"
Stop the "undefined reference to `yywrap'" error
%option noyywrap
Stop the "warning: 'yy_top_state' defined but not used" error
%option noyy_top_state
read string as input instead of file pointer
# in scanner
YY_BUFFER_STATE str_buffer;
void scan_begin(const char * cmd)
{
str_buffer = cmdline_scan_string(cmd);
}
void scan_end ()
{
cmdline_flush_buffer(str_buffer);
cmdline_delete_buffer(str_buffer);
}
# in main:
// cmdline parsing
ostringstream oss;
for(int i=1;i<argc;i++) oss << argv[i] << " ";
scan_begin(oss.str().c_str());
cmdlineparse();
scan_end();
Vairables in flex
- yytext points on the actual textstring which fits a specific regular expression in you flex file.
- yyleng number of characters in yytext
- yyin points by default to stdin
- yyout points by default to stdout
functions in flex
- yymore multiple use of a pattern
- yyless push back string which was read
- input read next character from input stream
- output(c) give c to stdout
- unput(c) push back c into input
- yywrap() actions after reaching the end of the input stream.
If return value is 1 then flex will be abadoned. If return value is 0 then yywrap can append another input stream.
predefined macros
- ECHO gives out the content of yytext.
start conditions
%s asdf
%S asdf
%start asdf
%swhatever asdf
defines 'asdf' as start rule which you can use with command 'begin'
begin 0
changes into normal mode
%s replace
^# { ECHO; BEGIN replace; }
\n { ECHO; BEGIN 0; }
<replace>PATTERN printf("asdf");
This example takes the input and if a line starts with # the normal mode switchs to rule 'replace' and if any string PATTERN would be found it will be replaced by 'asdf'. After the linefeed it would switch back to normal mode.
meta characters
\ ^ $ . [ ] | ( ) * + ? { } " / % < >
- ^ begin of line
- $ end of line
- . arbitrary character except \n
- \n linefeed. See below for further explanations.
classes of characters
complement
[^A-Z]
all characters except one between A and Z
alternation
he|she|it
meets string as he, she or it
[tT]he\ (good|bad)\ story.
meets "The good story" and "the bad story".
concatenation
abc"++"
"abc++"
abc\+\+
all three expresions meet "abc++".
one,more or nothing
(r)* no or more occurrences of regular expression r. The empty string also meets this.
(r)+ one or more occurrences of regular expression r.
(r)? no or one occurrences of r.
The brackets define a part of the string as combined.
repitions
[AEIOUaeiou]{2,2}
meets double vocals.
(reg){n1,n2}
meets occurences between n1 and n2.
meet line patterns with \n (linefeed)
^.*$
^.*\n
Both regular expressions meet a line of the input but the difference lies in the last character \n. In the first case the linefeed does not go into yytext. In the second case it goes into yytext.
flex with bison
paramters:
- -d: Write an extra output file containing macro definitions for the token type names defined in the grammar and the semantic value type YYSTYPE, as well as a few extern variable declarations. This creates a file y.tab.h with:
#define IF 4711
#define ELSE 4712
.
.
which can be included in the definition part of the lex file:
%{
# include "y.tag.h"
%}
Steps are:
- bison -d example.y
creates y.tab.c and y.tab.h
- flex example.lex
generates lex.yy.c
- gcc lex.yy.c y.tab.c -lfl
applications of flex