• Non ci sono risultati.

Principles of Programming Languages

N/A
N/A
Protected

Academic year: 2022

Condividi "Principles of Programming Languages"

Copied!
32
0
0

Testo completo

(1)

Principles of Programming Languages

h"p://www.di.unipi.it/~andrea/Dida2ca/PLP-16/

Prof. Andrea Corradini

Department of Computer Science, Pisa

•  Lexical analysis: implemen=ng a scanner

Lesson 5!

(2)

2

The Reason Why Lexical Analysis is a Separate Phase

•  Simplifies the design of the compiler

–  LL(1) or LR(1) parsing with 1 token lookahead would not be possible (mul=ple characters/tokens to match)

•  Provides efficient implementa=on

–  Systema=c techniques to implement lexical analyzers by hand or automa=cally from specifica=ons

–  Stream buffering methods to scan input

•  Improves portability

–  Non-standard symbols and alternate character

encodings can be normalized (e.g. UTF8, trigraphs)

(3)

Main goal of lexical analysis:

tokeniza=on

Lexical analyzer or

Scanner

y := 31 + 28*x

Parser

<id, “ y”> < assign, > <num, 31> <‘+’, > <num, 28> <‘*’, > <id, “ x”>

token

(lookahead)

tokenval

source code

(4)

4

Addi=onal tasks of the Lexical Analyzer

•  Remove comments and useless white spaces / tabs from the source code

•  Correlate error messages of the parser with source code (e.g. keeping track of line

numbers)

•  Expansion of macros

(5)

Interac=on of the Lexical Analyzer with the Parser

Lexical

Analyzer Parser

Source Program

Token, tokenval

Symbol Table

Get next token

error error

(6)

How are tokens determined?

•  The source programming language is defined by a CFG, used by the parser

•  The tokens are just the terminal symbols of the CFG

6

(7)

Tokens, Pa\erns, and Lexemes

•  A token is a pair <token name, a"ribute>

–  The token name (e.g. id, num, div, geq, …) iden=fies the category of lexical units

–  The a\ribute is op=onal

–  NOTE: most o^en, one refers to a token using the token name only

•  A lexeme is a character string that makes up a token

–  For example: abc, 123, \, >=

•  A pa1ern is a rule describing the set of lexemes belonging to a token

–  For example: “le#er followed by le#ers and digits”, “non-empty sequence of digits”, “character ‘\’”, “character ‘>’ followed by ‘=‘”

•  The scanner reads characters from the input =ll when it

recognizes a lexeme that matches the pa\erns for a token

(8)

How are tokens determined?

Token name Informal description Sample lexemes

if else relation

id number

literal

Characters i, f Characters e, l, s, e

< or > or <= or >= or == or !=

Letter followed by letter and digits Any numeric constant

Anything but " sorrounded by "

if else

<=, !=

pi, score, D2 3.14159, 0, 6.02e23

"core dumped"

8

•  The source programming language is defined by a CFG, used by the parser

•  The tokens are just the terminal symbols of the CFG

Examples of tokens

(9)

A\ributes of tokens

•  Needed when the pa\ern of a token matches different lexemes

•  We assume single a\ribute, but can be structured

•  Typically ignored by parsing, but used in subsequent compila=on phases (sta=c analysis, code genera=on, op=miza=on)

•  Kind of a\ribute depends on the token name

•  Iden=fiers have several info associated (lexeme, type, posi=on of defini=on,…)

–  Typically inserted as entries in a symbol table, and the

a\ribute is a pointer to the simbol-table entry

(10)

Reading input characters

•  Requires I/O opera=ons: efficiency is crucial

•  Lookahead can be necessary to iden=fy a token

•  Buffered input reduces I/O opera=ons

•  Naive implementa=on makes two tests for each character

–  End of buffer?

–  Mul=way branch on the character itself

•  Use of “sen=nels” encapsulate the end-of-buffer test into the mul=way branch

10

(11)

Buffered input to Enhance Efficiency

* M

=

E C * * 2 eof

Current token

lexeme beginning forward (scans

ahead to find pa\ern match)

if (forward at end of first half) then begin reload second half ;

forward : = forward + 1 end

else if (forward at end of second half) then begin reload first half ;

move forward to beginning of first half end

else forward : = forward + 1 ; Block I/O

Block I/O Executed for each

input character

(12)

Algorithm: Buffered I/O with Sen=nels

eof

*

= M

E C * * 2 eof eof

Current token

lexeme beginning forward (scans

ahead to find pa\ern match)

forward : = forward + 1 ;

if (forward is at eof) then begin

if (forward at end of first half) then begin reload second half ;

forward : = forward + 1 end

else if (forward at end of second half) then begin reload first half ;

move forward to beginning of first half end

else / * eof within buffer signifying end of input * / terminate lexical analysis

end 2nd eof ⇒ no more input ! Block I/O

Block I/O

12

Executed only is next character is eof

(13)

Specifica=on of Pa\erns for Tokens:

Recalling some basic defini=ons

•  An alphabet Σ is a finite set of symbols (characters)

•  A string s is a finite sequence of symbols from Σ

–  ⏐s⏐ denotes the length of string s

–  ε denotes the empty string, thus ⏐ε⏐ = 0 –  Σ* denotes the set of strings over Σ

•  A language L over Σ is a set of strings over alphabet Σ

•  Thus L ⊆Σ* , or L ∈ 2

Σ*

–  2

X

is the powerset of X, i.e. the set of all subsets of X

•  The concatenaCon of strings x and y is denoted by xy

•  ExponenCaCon of a string s: s

0

= ε s

i

= s

i-1

s for i > 0

(14)

14

Opera=ons on Languages

•  Languages are sets (of strings) thus all

opera=ons on sets are defined over them

–  Eg. Union: L ∪ M = {s ⏐ s ∈ L or s ∈ M}

•  Addi=onal opera=ons li^ to languages opera=ons on strings

–  ConcatenaCon LM = {xy ⏐ x ∈ L and y ∈ M}

–  ExponenCaCon L

0

= {ε}; L

i

= L

i-1

L

•  Closure operators

–  Kleene closure L

*

= ∪

i=0,…,∞

L

i

–  PosiCve closure L

+

= ∪

i=1,…,∞

L

i

(15)

Language Opera=ons: Examples

L = {a, b, ab, ba } D = {1, 2, ab, b} Assuming Σ = {a,b,1,2}

•  L ∪ D = { a, b, ab, ba, 1, 2 }

•  LD = {a1, a2, aab, ab, b1, b2, bab, bb, ab1, ab2, abab, abb, ba1, ba2, baab, bab }

•  L

2

= { aa, ab, aab, aba, ba, bb, bab, bba, abb, abab, abba, baa, bab, baab, baba}

•  D* = { ε, 1, 2, ab, b, 11, 12, …, 111, 112, …, 1111, 1112,

… }

•  D

+

= D* - { ε }

(16)

16

Regular Expressions:

syntax and seman=cs

•  Given an alphabet Σ, a regular expression over Σ denotes a language over Σ and is defined as follows:

•  Basis symbols:

–  ε is a regular expression deno=ng language {ε}

–  a is a regular expression deno=ng {a}, for each a ∈ Σ

•  If r and s are regular expressions deno=ng languages L(r) and L(s) respec=vely, then

–  (r)⏐(s) is a regular expression deno=ng L(r) ∪ L(s) –  (r)(s) is a regular expression deno=ng L(r)L(s) –  (r)* is a regular expression deno=ng L(r)* –  (r) is a regular expression deno=ng L(r)

•  A language defined by a regular expression is called a

regular language

(17)

Regular Expressions:

conven=ons and examples

•  Syntac=cal conven=ons to avoid too many brackets:

–  Precedence of operators: (_)

*

> (_)( _) > (_)|(_) –  Le^-associa=vity of all operators

–  Example: (a)⏐((b)

*

(c)) can be wri\en as a⏐b

*

c

•  Examples of regular expressions (over Σ = {a, b}):

–  a|b denotes { a, b }

–  (a|b)(a|b) denotes { aa, ab, ba, bb } –  a

*

denotes { ε, a, aa, aaa, aaaa, … }

–  (a|b)

*

denotes { ε, a, b, aa, ab, …, aaa, aab, … } = Σ

*

–  (a

*

b

*

)

*

denotes ?

•  Two regular expressions are equivalent if they

denote the same language. Eg: (a|b)

*

= (a

*

b

*

)

*

(18)

Some Algebraic Proper=es of Regular Expressions

LAW DESCRIPTION

r | s = s | r

r | (s | t) = (r | s) | t (r s) t = r (s t)

εr = r rε = r

r* = ( r | ε )*

r ( s | t ) = r s | r t ( s | t ) r = s r | t r

r** = r*

| is commuta=ve

| is associa=ve

concatena=on is associa=ve concatena=on distributes over |

rela=on between * and ε

ε is the iden=ty element for concatena=on

* is idempotent

18

•  Equivalence of regular expressions is decidable

•  There exist complete axioma=za=ons

(19)

Regular Defini=ons

•  Provide a convenient syntax, similar to BNF, introducing names to denote regular expressions.

•  A regular definiCon has the form d

1

→ r

1

d

2

→ r

2

d

n

→ r

n

where each r

i

is a regular expression over Σ ∪ {d

1

, …, d

i-1

}

•  Recursion is forbidden! digits ! digit | digit digits wrong!

•  Itera=vely replacing names with the corresponding defini=on yields a single regular expression for d

n

letter → A⏐B⏐…⏐Z⏐a⏐b⏐…⏐z digit → 0⏐1⏐…⏐9

id → letter ( letter⏐digit )

*

(20)

Extensions of Regular Expressions

•  Several operators on regular expressions have been proposed, improving expressivity and conciseness

•  Modern scrip=ng languages are very rich

•  Clearly, each new operator must be definable with a regular expression

•  Here are some common conven=ons

20

[xyz] match one character x, y, or z

[^xyz] match any character except x, y, and z [a-z] match one of a to z

r

+

positive closure (match one or more occurrences)

r

?

optional (match zero or one occurrence)

(21)

Recognizing Tokens

•  Tokens are specified using regular expressions/

defini=ons

•  From the regular defini=on we can generate the code for recognizing tokens

•  Running example CFG:

•  The tokens are:

if, then, else,
 relop, id, num "

stmt → if expr then stmt

if expr then stmt else stmt ⏐ ε

expr → term relop term term

term → id

(22)

Pattern of

lexeme Token Attribute-Value

Any ws if then else Any id Any num

<

<=

=

< >

>

>=

- if then else id num relop relop relop relop relop relop

- - - -

pointer to table entry pointer to table entry LT

LE EQ NE GT GE

22

Running example: Informal specifica=on

of tokens and their a\ributes

(23)

Regular Defini=ons for tokens

•  The specifica=on of the pa\erns for the tokens is provided with regular defini=ons

letter → [A-Za-z]

digit → [0-9]

digits → digit

+

if → if then → then else → else

relop → < <= <> > >= =

id → letter (letter | digit )

*

(24)

From Regular Defini=ons to code

•  From the regular defini=ons we first extract a transiCon diagram, and next the code of the scanner.

•  In the example the lexemes are recognized either when they are completed, or at the next character. In real situa=ons a longer lookahead might be necessary.

•  The diagrams guarantee that the longest lexeme is iden=fied.

24

(25)

Coding Regular Defini=ons in TransiCon Diagrams

0 1 2

6

3 4 5

7 8

return(relop, LE) return(relop, NE) return(relop, LT) return(relop, EQ)

return(relop, GE) return(relop, GT)

start <

=

>

=

>

= other other

*

*

letter or digit

relop → <<=<>>>==

id → letter ( letterdigit )

*

(26)

Transi=on diagram for unsigned numbers

num → digit

+

(. digit

+

)? ( E (+-)? digit

+

)?

Coding Regular Defini=ons in TransiCon Diagrams (cont.)

̇ͯͯᗮ

጖ဤฆ਺ཱུበᗮࡐᅻ਺ᗮᅻ਺हဤஸ್ཱུᔎ਺়ᗮ್ཱུᗮႼᅻ਺૤਺ᅻ਺ཱུह਺ᗮ጖ဤᗮ*ťᑌఀ਺ཱུᗮ጖ఀ਺ᗮเ਺ᒏ਺༌਺ᗮ༌ࡐ጖हఀ਺በᗮ࣓ဤ጖ఀᗮ Ⴜࡐ጖጖਺ᅻཱུበȪᗮ ߖ਺ᗮ'؛ ؛Ꮀበ਺ᗮ጖ఀ್በᗮࡐႼႼᅻဤࡐहఀᗮ್ཱུᗮဤᎰᅻᗮ਺ᒏࡐ༌Ⴜเ਺ăᗮᑌఀ್हఀᗮ್በᗮᑌఀᓆᗮ጖ఀ਺ᗮ በ጖ࡐ጖਺በᗮ್ཱུᗮ֍್ஸȪᗮͯȪ̇Υᗮࡐᅻ਺ᗮᎰཱཱུུᎰ༌࣓਺ᅻ਺়Ȫᗮ

֍್ஸᎰᅻ਺ᗮͯȪ̇ΥкᗮזᓆႼဤ጖ఀ਺጖್हࡐเᗮ጖ᅻࡐཱུበ್጖್ဤཱུᗮ়್ࡐஸᅻࡐ༌ᗮ૤ဤᅻᗮ጖ఀ਺ᗮฆ਺ᓆᑌဤᅻ়ᗮ;Ϯ

—AFA—ť

ݬఀ਺ᗮ጖ᅻࡐཱུበ್጖್ဤཱུᗮ়್ࡐஸᅻࡐ༌ᗮ૤ဤᅻᗮඒਪ;በᗮ጖ఀࡐ጖ᗮᑌ਺ᗮበࡐᑌᗮ್ཱུᗮ֍್ஸȯᗮͯȪ̇·ᗮఀࡐበᗮࡐᗮበ್༌Ⴜเ਺ᗮበ጖ᅻᎰह጖Ꮀᅻ਺Ȭᗮ

ܺ጖ࡐᅻ጖್ཱུஸᗮ್ཱུᗮበ጖ࡐ጖਺ᗮ'್̓጖ᗮहఀ਺हฆበᗮ጖ఀࡐ጖ᗮ጖ఀ਺ᗮเ਺ᒏ਺༌਺ᗮ࣓਺ஸ್ཱུበᗮᑌ್጖ఀᗮࡐᗮเ਺጖጖਺ᅻᗮࡐ়ཱུᗮஸဤ਺በᗮ጖ဤᗮ በ጖ࡐ጖਺ᗮ̇˨ᗮ್૤ᗮበဤȪᗮ ߖ਺ᗮበ጖ࡐᓆᗮ್ཱུᗮበ጖ࡐ጖਺ᗮ̇˨ᗮࡐበᗮเဤཱུஸᗮࡐበᗮ጖ఀ਺ᗮ್ཱུႼᎰ጖ᗮहဤཱུ጖ࡐ್ཱུበᗮเ਺጖጖਺ᅻበᗮࡐ়ཱུᗮ়್ஸ್጖በȪᗮ ߖఀ਺ཱུᗮᑌ਺ᗮ୪ᅻበ጖ᗮ਺ཱུहဤᎰཱུ጖਺ᅻᗮࡐཱུᓆ጖ఀ್ཱུஸᗮ࣓Ꮀ጖ᗮࡐᗮเ਺጖጖਺ᅻᗮဤᅻᗮ়್ஸ್጖Āᗮᑌ਺ᗮஸဤᗮ጖ဤᗮበ጖ࡐ጖਺ᗮ ̇ ̇ ᗮࡐ়ཱུᗮ ࡐहह਺Ⴜ጖ᗮ጖ఀ਺ᗮเ਺ᒏ਺༌਺ᗮ૤ဤᎰ়ཱུȪᗮ ್ཱུܺह਺ᗮ጖ఀ਺ᗮเࡐበ጖ᗮहఀࡐᅻࡐह጖਺ᅻᗮ್በᗮཱུဤ጖ᗮႼࡐᅻ጖ᗮဤ૤ᗮ጖ఀ਺ᗮ়್਺ཱུ጖್୪਺ᅻĀᗮ ᑌ਺ᗮ༌Ꮀበ጖ᗮ ᅻ਺጖ᅻࡐह጖ᗮ ጖ఀ਺ᗮ್ཱུႼᎰ጖ᗮဤཱུ਺ᗮႼဤበ್጖್ဤཱུăᗮ ࡐ়ཱུᗮࡐበᗮ ়್በहᎰበበ਺়ᗮ್ཱུᗮܺ਺ह጖್ဤཱུᗮͯȮ·ʰ͐Āᗮᑌ਺ᗮ

਺ཱུ጖਺ᅻᗮᑌఀࡐ጖ᗮᑌ਺ᗮఀࡐᐕ਺ᗮ૤ဤᎰ়ཱུᗮ್ཱུᗮ጖ఀ਺ᗮበᓆ༌࣓ဤเᗮ጖ࡐ࣓เ਺ᗮࡐ়ཱུᗮ়਺጖਺ᅻ༌್ཱུ਺ᗮᑌఀ਺጖ఀ਺ᅻᗮᑌ਺ᗮఀࡐᐕ਺ᗮ ࡐᗮฆ਺ᓆᑌဤᅻ়ᗮဤᅻᗮࡐᗮ጖ᅻᎰ਺ᗮ়್਺ཱུ጖್୪਺ᅻȪᗮ

ݬఀ਺ᗮ጖ᅻࡐཱུበ್጖್ဤཱུᗮ়್ࡐஸᅻࡐ༌ᗮ૤ဤᅻᗮ጖ဤฆ਺ཱུᗮ1 ť್በᗮበఀဤᑌཱུᗮ್ཱུᗮ֍್ஸȪᗮͯȪ̇νĀᗮࡐ়ཱུᗮ್በᗮበဤᗮ

૤ࡐᅻᗮ጖ఀ਺ᗮ༌ဤበ጖ᗮ हဤ༌Ⴜเ਺ᒏᗮ়್ࡐஸᅻࡐ༌ᗮᑌ਺ᗮఀࡐᐕ਺ᗮበ਺਺ཱུȪᗮ ԉ਺ஸ್್ཱཱཱུུུஸᗮ್ཱུᗮበ጖ࡐ጖਺ᗮ ̇͐Āᗮ್૤ᗮᑌ਺ᗮበ਺਺ᗮࡐᗮ

়್ஸ್጖Āᗮᑌ਺ᗮஸဤᗮ጖ဤᗮበ጖ࡐ጖਺ᗮ ̇ͯȪᗮ צཱུᗮ጖ఀࡐ጖ᗮበ጖ࡐ጖਺Āᗮᑌ਺ᗮहࡐཱུᗮᅻ਺ࡐ়ᗮࡐཱུᓆᗮཱུᎰ༌࣓਺ᅻᗮဤ૤ᗮࡐ়়್጖್ဤཱུࡐเᗮ

়್ஸ್጖በȪᗮ זဤᑌ਺ᐕ਺ᅻĀᗮ್૤ᗮᑌ਺ᗮበ਺਺ᗮࡐཱུᓆ጖ఀ್ཱུஸᗮ࣓Ꮀ጖ᗮࡐᗮ়್ஸ್጖ᗮဤᅻᗮࡐᗮ়ဤ጖Āᗮᑌ਺ᗮఀࡐᐕ਺ᗮበ਺਺ཱུᗮࡐᗮཱུᎰ༌࣓਺ᅻᗮ

್ཱུᗮ጖ఀ਺ᗮ૤ဤᅻ༌ᗮဤ૤ᗮࡐཱུᗮ್ཱུ጖਺ஸ਺ᅻҲᗮ ,Ϯ್በᗮࡐཱུᗮ਺ᒏࡐ༌Ⴜเ਺Ȫᗮ ݬఀࡐ጖ᗮहࡐበ਺ᗮ್በᗮఀࡐ়ཱུเ਺়ᗮ࣓ᓆᗮ਺ཱུ጖਺ᅻ್ཱུஸᗮ በ጖ࡐ጖਺ᗮ͐˨Āᗮᑌఀ਺ᅻ਺ᗮᑌ਺ᗮᅻ਺጖Ꮀᅻཱུᗮ጖ဤฆ਺ཱུᗮ1 ťࡐ়ཱུᗮࡐᗮႼဤ್ཱུ጖਺ᅻᗮ጖ဤᗮࡐᗮ጖ࡐ࣓เ਺ᗮဤ૤ᗮहဤཱུበ጖ࡐཱུ጖በᗮ ᑌఀ਺ᅻ਺ᗮ ጖ఀ਺ᗮ ૤ဤᎰ়ཱུᗮ เ਺ᒏ਺༌਺ᗮ ್በᗮ ਺ཱུ጖਺ᅻ਺়Ȫᗮ ݬఀ਺በ਺ᗮ ༌਺हఀࡐ್ཱུहበᗮ ࡐᅻ਺ᗮ ཱུဤ጖ᗮ በఀဤᑌཱུᗮ ဤཱུᗮ ጖ఀ਺ᗮ

়್ࡐஸᅻࡐ༌ᗮ࣓Ꮀ጖ᗮࡐᅻ਺ᗮࡐཱུࡐเဤஸဤᎰበᗮ጖ဤᗮ጖ఀ਺ᗮᑌࡐᓆᗮᑌ਺ᗮఀࡐ়ཱུเ਺়ᗮ়್਺ཱུ጖್୪਺ᅻበȪᗮ

֍್ஸᎰᅻ਺ᗮͯȪ̇νиᗮӕᗮ጖ᅻࡐཱུበ್጖್ဤཱུᗮ়್ࡐஸᅻࡐ༌ᗮ૤ဤᅻᗮᎰཱུበ್ஸཱུ਺়ᗮཱུᎰ༌࣓਺ᅻበᗮ

צ૤ᗮᑌ਺ᗮ ್ཱུበ጖਺ࡐ়ᗮ በ਺਺ᗮ ࡐᗮ ়ဤ጖ᗮ ್ཱུᗮ በ጖ࡐ጖਺ᗮ ̇ͮĀᗮ ጖ఀ਺ཱུᗮ ᑌ਺ᗮఀࡐᐕ਺ᗮࡐཱུᗮ ဤႼ጖್ဤཱུࡐเᗮ૤ᅻࡐह጖್ဤཱུȶᗮ

ܺ጖ࡐ጖਺ᗮ̇·ᗮ್በᗮ਺ཱུ጖਺ᅻ਺়Āᗮࡐ়ཱུᗮᑌ਺ᗮเဤဤฆᗮ૤ဤᅻᗮဤཱུ਺ᗮဤᅻᗮ༌ဤᅻ਺ᗮࡐ়়್጖್ဤཱུࡐเᗮ়್ஸ್጖በ҃ᗮበ጖ࡐ጖਺ᗮ̇Υᗮ್በᗮ Ꮀበ਺়ᗮ૤ဤᅻᗮ጖ఀࡐ጖ᗮႼᎰᅻႼဤበ਺Ȫᗮ צ૤ᗮᑌ਺ᗮበ਺਺ᗮࡐཱུᗮJ.Ϯ጖ఀ਺ཱུᗮᑌ਺ᗮఀࡐᐕ਺ᗮࡐཱུᗮ ဤႼ጖್ဤཱུࡐเᗮ਺ᒏႼဤཱུ਺ཱུ጖Āᗮ ᑌఀဤበ਺ᗮᅻ਺हဤஸ್ཱུ጖್ဤཱུᗮ್በᗮ጖ఀ਺ᗮෟဤ࣓ᗮဤ૤ᗮበ጖ࡐ጖਺በᗮ ̇νᗮ጖ఀᅻဤᎰஸఀᗮ ̇ДȪᗮ ܺఀဤᎰเ়ᗮᑌ਺Āᗮ್ཱུᗮበ጖ࡐ጖਺ᗮ ̇ΥĀᗮ

್ཱུበ጖਺ࡐ়ᗮ በ਺਺ᗮࡐཱུᓆ጖ఀ್ཱུஸᗮ࣓Ꮀ጖ᗮဤᅻᗮࡐᗮ ়್ஸ್጖Āᗮ ጖ఀ਺ཱུᗮ ᑌ਺ᗮ ఀࡐᐕ਺ᗮ हဤ༌਺ᗮ጖ဤᗮ጖ఀ਺ᗮ ਺়ཱུᗮဤ૤ᗮ጖ఀ਺ᗮ

૤ᅻࡐह጖್ဤཱུĀᗮ጖ఀ਺ᅻ਺ᗮ್በᗮཱུဤᗮ਺ᒏႼဤཱུ਺ཱུ጖Āᗮࡐ়ཱུᗮᑌ਺ᗮᅻ਺጖Ꮀᅻཱུᗮ጖ఀ਺ᗮเ਺ᒏ਺༌਺ᗮ૤ဤᎰ়ཱུĀᗮᐕ್ࡐᗮበ጖ࡐ጖਺ᗮ͐̇Ȫᗮ

26

(27)

From Individual Transi=on Diagrams to Code

•  Easy to convert each Transi=on Diagram into code

•  Loop with mul=way branch (switch/case) based on the current state to reach the instruc=ons for that state

•  Each state is a mul=way branch based on the next

input character

(28)

Coding the Transi=on Diagrams for Rela=onal Operators

TOKEN getRelop() "

{ "TOKEN retToken = new(RELOP);


"while(1) { /* repeat character processing "

" "until a return or failure occurs */"

" "switch(state) { "

" " "case 0: "c = nextChar();


" " " " "if(c == '<') state = 1;


" " " " "else if (c == '=') state = 5; 


" " " " "else if (c == '>’) state = 6;


" " " " "else fail() ; /* lexeme is not a relop */ "

" " " " "break; "

" " "case 1: ... "

" " "..."

" " "case 8: "retract();"

" " " " "retToken.attribute = GT; "

" " " " "return(retToken);"

} } }

0 1 2

6

3 4 5

7 8

return(relop, LE) return(relop, NE) return(relop, LT) return(relop, EQ)

return(relop, GE) return(relop, GT)

start <

=

>

=

>

= other other

*

*

28

(29)

Puxng the code together

The transi=on diagrams for the various tokens

can be tried sequen=ally:

on failure, we re-scan the input trying another diagram.

int fail()

{ forward = token_beginning;

switch (state) {

case 0: start = 9; break;

case 9: start = 12; break;

case 12: start = 20; break;

case 20: start = 25; break;

case 25: recover(); break;

default: /* error */

token nexttoken() { while (1) {

switch (state) {

case 0: c = nextchar();

if (c==blank || c==tab || c==newline) { state = 0;

lexeme_beginning++;

}

else if (c==‘<’) state = 1;

else if (c==‘=’) state = 5;

else if (c==‘>’) state = 6;

else state = fail();

break;

case 1:

case 9: c = nextchar();

if (isletter(c)) state = 10;

else state = fail();

break;

case 10: c = nextchar();

if (isletter(c)) state = 10;

else if (isdigit(c)) state = 10;

(30)

Puxng the code together:

Alterna=ve solu=ons

•  The diagrams can be checked in parallel

•  The diagrams can be merged into a single one, typically non-determinisCc: this is the approach we will study in depth.

30

(31)

Lexical errors

•  Some errors are out of power of lexical analyzer to recognize:

fi (a == f(x)) … "

•  However, it may be able to recognize errors like:

d = 2r "

•  Such errors are recognized when no pa\ern

for tokens matches a character sequence

(32)

Error recovery

•  Panic mode: successive characters are ignored un=l we reach to a well formed token

•  Delete one character from the remaining input

•  Insert a missing character into the remaining input

•  Replace a character by another character

•  Transpose two adjacent characters

•  Minimal Distance

32

Riferimenti

Documenti correlati

•  Every nonterminal has one (recursive) procedure responsible for parsing the nonterminal’s syntactic category of input tokens. •  When a nonterminal has multiple

•  An NFA accepts an input string x (over Σ ) if and only if there is some path with edges labeled with symbols from x in sequence from the start state to some.. accepting state

–  Transla=ng short-circuit Boolean expressions and flow-of- control statements with backpatching lists.. How does the code

special end symbol # to make accepting states important: the new expression is r#. •  Construct a syntax tree

•  A backward analysis propagates informa@on in the opposite direc@on in which the program flows. •  A forward analysis propagates informa@on in the same direc@on in which

/* Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to

•  LALR parsing (Look-Ahead LR) merges two or more LR(1) state into one state to reduce table size. •  Less powerful

§  The types of variables and parameters are not declared, and cannot be inferred by the Python compiler.. So run-time type checks are needed to detect