Understand a basic Lex program that recognizes words, numbers, and whitespace.
1. Lex Program Structure
A Lex program has three sec�ons, separated by %%:
1. Defini�ons
%%
2. Rules
%%
3. User Code (op�onal)
2. Example
%{
#include <stdio.h>
%}
%%
[0-9]+ { prin�("Number: %s\n", yytext); }
[a-zA-Z]+ { prin�("Word: %s\n", yytext); }
[ \t\n]+ { /* Ignore whitespace */ }
. { prin�("Unknown character: %s\n", yytext); }
%%
int main() {
yylex();
return 0;
}
3. Explana�on
%{ ... %}
• C code to include in the generated C file. Here we include <stdio.h>.
%% — Rules sec�on
Each line is a rule:
• [0-9]+ → matches one or more digits → prints "Number"
• [a-zA-Z]+ → matches one or more leters → prints "Word"
• [ \t\n]+ → matches whitespace → does nothing (ignored)
• . → matches any single character → prints "Unknown character"
yytext
• A global variable containing the matched text.
yylex()
• The main func�on generated by Lex that performs the tokeniza�on.
4. How to Run
1. Save as sample.l
2. Use Flex and GCC to compile:
flex example.l
gcc [Link].c -o lexer
./lexer
3. Type input like:
hello 1234 $
Output:
Word: hello
Number: 1234
Unknown character: $
Example 2:
%{
#include<stdio.h>
%}
%%
if |
else |
prin�{prin�("%s is keyword",yytext);}
[0-9]+ {prin�("%s is number",yytext);}
[a-zA-Z]+ {prin�("%s is word",yytext);}
.|\n {ECHO;}
%%
int main()
prin�("Enter the string:");
yylex();
int yywrap()
return 1;
This Lex code reads a string from the user and classifies parts of it as:
• Keywords (if, else, prin�)
• Numbers (like 123)
• Words (like hello)
• Everything else (printed as-is)
1. SECTION 1: Header (C Code Block)
%{
#include<stdio.h>
%}
Explana�on:
• %{ ... %} is a block where you can write C code that gets copied into the top of
the generated .c file.
• Here, #include <stdio.h> is needed to use prin�().
2. SECTION 2: Lexical Rules
%%
if |
else |
prin� {prin�("%s is keyword",yytext);}
[0-9]+ {prin�("%s is number",yytext);}
[a-zA-Z]+ {prin�("%s is word",yytext);}
.|\n {ECHO;}
%%
Explana�on:
Each rule consists of:
• A patern (a regular expression)
• An ac�on ({ ... }) that is run when that patern is matched
Let's go through each one:
Keyword Rule
if |
else |
prin� {prin�("%s is keyword",yytext);}
This matches the words if, else, or prin�.
• The | operator means "OR" — so this is actually three rules combined.
• If any of them match, it prints:
• if is keyword
• else is keyword
• prin� is keyword
• yytext contains the matched word (e.g., "if").
Number Rule
[0-9]+ {prin�("%s is number",yytext);}
• This matches one or more digits, i.e., any integer number.
• For example, if you type 123, it will print:
• 123 is number
Word Rule
[a-zA-Z]+ {prin�("%s is word",yytext);}
• This matches any sequence of leters, not already matched by earlier rules.
• If you type hello, it prints:
• hello is word
Note: prin�, if, and else will be caught by the first rule, so this rule will only match
other words like main, value, etc.
Catch-all Rule
.|\n {ECHO;}
• . matches any single character.
• \n matches newline.
• Together, this means: for any character not matched above, just echo it back
using ECHO;
ECHO is a Lex macro that prints the matched text to standard output.
So it ensures unexpected characters or whitespace are not silently ignored.
3. SECTION 3: Main Func�on
int main()
prin�("Enter the string:");
yylex();
• main() prints a prompt and calls yylex() to start tokenizing the input.
4. yywrap() Func�on
Part Role
int yywrap() yytext The current matched text
yylex() Starts tokenizing input
{ yywrap() Signals end of input
ECHO; Prints unmatched characters
return 1;
[0-9]+ Matches numbers
} [a-zA-Z]+ Matches words
`if else
What is yywrap()?
• yylex() calls yywrap() when it reaches the end of the input.
• Returning 1 tells Lex: "Stop scanning" — we’re done.
(If you don't define yywrap(), you may get linker errors.)