Download .md

Compiler Construction

Institution: Rivers State University, Nkpolu-Oroworukwo, Port Harcourt Course Code: CMS 709 Course Title: Compiler Construction Session: 2024/2025 Topic: Lexical Analysis Date: 15/02/16


Lexical Analysis

This is the first phase of a compiler.

Lexical Analysis: The process of taking an input string of characters (such as source code of a computer program) and producing a sequence of symbols called "lexical tokens" or just "tokens".

The lexical analyzer reads the source text and thus, it may perform certain secondary tasks:

The interaction with the parser is usually done by making the lexical analyzer be a sub-routine of the parser.

flowchart LR
    LA[Lexical Analyser] -->|Token| P[Parser]
    P -->|get next token| LA
    LA --- ST[Symbol Table]
    P --> output[-->]

Fig (a): Interaction of Lexical Analyser with the Parser


Why Separate LA from Syntax Analysis?


Tokens, Patterns and Lexemes

Token

Also called "word". Is:

Pattern

The set of strings for which the "same" token is produced. Or:

A rule that describes the set of strings associated to a token. Expressed as a "regular expression" and describing how a particular token can be formed. e.g.:

[A-Za-z]  [A-Za-z_0-9]*

The pattern "matches" each string in the set. e.g.: float, (l+d+), =, -, d+, ;

Lexeme

The sequence (actual) of characters forming a specific instance of a token. e.g.: "num" or "float", "abs_zero_kelvin", "e_yn_m", 273, ".", etc.


Example: Tokens, Lexemes and Patterns

Token Sample Lexeme Description of Pattern (informal)
const const const
if if if
relation <, <=, =, >=, >, != `<
id pi, count, D, a letter · (letter | digit)*
num 3.1426, 0, 6, 6.22 any numeric constant
literal "core dumped" any x b/w " and " except "

Note: In Pascal statement const pi = 3.1426, the substring "pi" is a lexeme for the token "identifier".

Note: When more than one pattern matches a lexeme, the lexical analyzer must provide additional info about the particular lexeme. e.g.: Pattern "num" matches '0' and '1'. It is essential for code generation to know which string was actually matched. The lexical analyzer collects info about tokens into their associated attributes.


Tokens in Practice (Attributes)

In practice, a token has only a single attribute, a pointer to the symbol table entry in which the info about the token is kept such as:

e.g. FORTRAN Statement:

E = M * C ** 2

Tokens and associated attributes:


Tokens in Programming Languages


Difficulties in LA


Errors in LA

LA cannot catch any significant errors, except for simple errors such as illegal symbols, etc. In such cases, LA skips xtrs in the input until a well-formed token is found.


Specification and Recognition of Tokens

(i) Regular Definitions

A mechanism based on "regular expressions" and very popular for specification of tokens. It has been implemented in the lexical analyzer generator tool, LEX. We study regular expressions first, and then token specification using LEX.

(ii) Transition Diagrams

Transition Diagrams (TD) are usually used to model LA by translating them to programs by hand.


Type 0: Type 3 Languages

Type 0, Type 3 languages are finite representations of respective languages.

Examples of Languages

Let Σ = {a, b, c}


Language Representations


Input Buffering: General Idea

Some tokens such as parentheses do not really have values, and so the evaluator function for these can return nothing. The evaluator for integers, identifiers, and strings can be considerably more complex. Sometimes evaluators can suppress a lexeme entirely, concealing it from the parser, which is useful for white space and comments.


Stages of Lexical Analyzer

(a) Scanner

This is based on a finite state machine. If it lands on an accepting state, it takes note of the type and position of the acceptance, and continues. Sometimes it lands on a "dead state", which is a non-accepting state. When the LA lands on a dead state, it is done. The last accepting state is the one that represents the type and length of the longest valid lexeme. The "extra" non-valid character should be "returned" to the input buffer.

(b) Evaluator

This goes over the characters of the lexeme to produce a value. The lexeme's type combined with its value is what properly constitutes a "token", which can be given to a parser.


Differences b/w TD and FSA

To consider different kinds of lexeme, we usually build separate DFAs (or TDs) corresponding to the regular expressions for each kind of lexeme, then merge them into a single combined DFA (or TD).


Input Buffer Pointers


Lexical Analyzer Specification

To specify a lexical analyzer we need a "state machine", sometimes called Transition Diagram (TD), which is similar to FSA (Finite State Automata).

TDs depict the actions that take place when the lexer is called by the parser to get the next token.


Example: FSA vs TD Diagrams

Fig (a): FSA for digits

stateDiagram-v2
    direction LR
    [*] --> 0
    0 --> 1 : [0-9]
    1 --> 1 : [0-9]
    1 --> [*]

Fig (b): TD for digits with retraction

stateDiagram-v2
    direction LR
    [*] --> 0
    0 --> 1 : [0-9]
    1 --> 1 : [0-9]
    1 --> 2 : other *

State 2 is the accepting state; * on transition from state 1 to 2 means retraction (input pointer must be retracted).


Recognizing Keywords

Keywords have the same pattern as identifiers but do not correspond to the token "identifier".

Two solutions are possible:

(A) Keywords as Identifiers

This technique for separating identifiers from keywords consists in initializing appropriately the symbol in which information about identifiers is saved. For instance, we enter the strings "if", "then" and "else" into the symbol table before any characters in the input stream are seen.

Entry Type
do Keyword
end Keyword
for Keyword
while Keyword
... ...
cont Identifier

(B) Regular Expressions for All Keywords


TD Example 1: Combined TD for Identifiers, Keywords and Numbers

flowchart LR
    0 -->|letter| 1
    0 -->|digit| 3
    0 -->|d| 5
    1 -->|letter/digit| 1
    1 -->|other *| 2([IDENTIFIER])
    3 -->|digit| 3
    3 -->|other *| 4([INTEGER])
    5 -->|other *| 6
    5 -->|o| 7
    7 -->|other *| 8
    7 -->|n| 9
    9 -->|e| 10([one])
    9 -->|other *| 11

TD Example 2: Unsigned/Signed Integers, Addition (+) and Increment (++)

flowchart LR
    0 -->|digit| 6
    0 -->|+| 1
    1 -->|other *| 2([ADD])
    1 -->|+| 3
    3 -->|other *| 4([ADD])
    3 -->|+| 5([INC R])
    6 -->|digit| 6
    6 -->|other *| 7([INTEGER])
    6 -->|+| 8
    8 -->|digit| 6

Transition Table: TD Example 2

State + D Token Retraction
0 1 8 6 , ,
1 3 2 2 , ,
2 , , , ADD 1
3 5 4 4 , ,
4 , , , ADD 2
5 , , , INCR 2 (or 0)
6 7 6 6 , ,
7 , , , INTEGER 1
8 error error , , ,

Implementation of Lexical Analyzer

Different ways of creating a lexical analyzer:

(i) Automatic Generator (e.g. LEX or FLEX)

(ii) Write LA by Hand Using HLL

(iii) Write LA Using Low-Level Language

Automatic Tool Input Specification:


Priority of Tokens

(A) Longest Lexeme

(B) First-listed Matching Pattern

The following regular expressions appear in lexical specification: