Lexical Analysis: Textbook:Modern Compiler Design
Lexical Analysis: Textbook:Modern Compiler Design
A motivating example
Create a program that counts the number of lines in a given input text file
Solution
int num_lines = 0;
%% \n ++num_lines; . ; %% main() { yylex(); printf( "# of lines = %d\n", num_lines); }
Solution
int num_lines = 0;
initial %% \n ++num_lines; . ; %% main() { yylex(); printf( "# of lines = %d\n", num_lines); } newline ;
Outline
Roles of lexical analysis What is a token Regular expressions and regular descriptions Lexical analysis Automatic Creation of Lexical Analysis Error Handling
Tokens
syntax analysis Abstract syntax tree semantic analysis Annotated Abstract syntax tree Back-End
Fin. Assembly
Example Tokens
Type Examples
Example NonTokens
Type Examples
Example
void match0(char *s) /* find a zero */
{ if (!strncmp(s, 0.0, 3))
return 0. ;
} VOID ID(match0) LPAREN CHAR DEREF ID(s) RPAREN LBRACE IF LPAREN NOT ID(strncmp) LPAREN ID(s) COMMA STRING(0.0) COMMA NUM(3) RPAREN RPAREN RETURN REAL(0.0) SEMI RBRACE EOF
What is a token?
Defined by the programming language Can be separated by spaces Smallest units Defined by regular expressions
Regular Expressions
Regular Descriptions
EBNF where non-terminals are fully defined before first use
letter [a-zA-Z] digit [0-9] underscore _ letter_or_digit letter|digit underscored_tail underscore letter_or_digit+ identifier letter letter_or_digit* underscored_tail
token description
A token name A regular expression
Flex
Input
regular expressions and actions (C code)
Output
A scanner program that reads the input and applies actions when input regular expression is matched
regular expressions
flex
input program scanner tokens
Nave approach on regular expressions (dotted items) Construct non deterministic finite automaton over items Convert to a deterministic Minimize the resultant automaton Optimize (compress) representation
Dotted Items
Example
T a+ b+ Input aab After parsing aa
T a+ b+
Item Types
Shift item
In front of a basic pattern A (ab)+ c (de|fe)*
Reduce item
At the end of rhs A (ab)+ c (de|fe)*
Basic item
Shift or reduce items
Character Moves
For shift items character moves are simple
Tc
Digit [0-9]
c 7
c
7
Tc
T [0-9]
Moves
For non-shift items the situation is more complicated What character do we need to see? Where are we in the matching? T a* T (a*)
Moves
I [0-9]+ F [0-9]*.[0-9]+
Input 3.1;
F ([0-9])*.([0-9])+ F ([0-9])*.([0-9])+ F ( [0-9] )*.([0-9])+ F ( [0-9])*.([0-9])+ F ( [0-9])* .([0-9])+ F ( [0-9])*. ([0-9])+ F ( [0-9])*. ([0-9])+ F ( [0-9])* .([0-9])+
F ( [0-9])*. ( [0-9] )+
F ( [0-9])*. ( [0-9])+ F ( [0-9])*. ( [0-9])+
Concurrent Search
How to scan multiple token classes in a single run?
I [0-9]+ F [0-9]*.[0-9]+
Input 3.1;
I ([0-9])+
I ([0-9])+ I ( [0-9] )+
I ([0-9])+ I ( [0-9])+
F ([0-9])*.([0-9])+
F ([0-9])*.([0-9])+ F ( [0-9] )*.([0-9])+
F ([0-9])*.([0-9])+
F ([0-9])* .([0-9])+
F ( [0-9])* .([0-9])+
F ( [0-9])*. ([0-9])+
Moves
I ([0-9]+)
F ([0-9]*).[0-9]+ F ( [0-9]*) .[0-9]+
I ([0-9])+
[0-9] I ( [0-9])+
[0-9]
F ( [0-9] *).[0-9]+
.
F [0-9]*. ([0-9]+)
F [0-9]*. ( [0-9] +)
I ( [0-9])+
F [0-9]*. ( [0-9] +)
Efficient Scanners
Construct Deterministic Finite Automaton
Every state is a set of items Every transition is followed by an -closure When a set contains two reduce items select the one declared first
Compress representation
I [0-9]+ F [0-9]*.[0-9]+
[0-9] I ( [0-9])+ F ( [0-9] *).[0-9]+ I ( [0-9])+ I ([0-9])+ F ([0-9]*).[0-9]+ F ( [0-9]*) .[0-9]+ [0-9]
.|\n [^0-9.]
Sink
[^0-9]
[^0-9.]
Scanning 3.1;
input 3.1; 3 .1; 3. 1; 3.1 ; state 1 2 3 4 next state 2 3 4 Sink last token I I F F
[0-9] [0-9]
[^0-9.]
1
[0-9] [^0-9.] . .
Sink
2 I
3
[0-9]
[^0-9]
4 F
Scanning aaa
[^a]
[.\n]
T1 a+; T2 a input aaa$ a aa$ a a a$ aaa$ state 1 2 4 4 next state 2 4 4 Sink last token T1 T1 T1
1
[a] [^a;]
Sink
[.\n] ;
;
T1
2
[a]
T1
[^a;]
[a]
T1
Error Handling
Illegal symbols Common errors
Missing
Creating a lexical analysis by hand Table compression Symbol Tables Handling Macros Start states Nested comments
Summary
For most programming languages lexical analyzers can be easily constructed automatically Exceptions:
Fortran PL/1