0% found this document useful (0 votes)
5 views104 pages

Language Syntax

The document discusses the syntax of programming languages, emphasizing the importance of clearly specified syntax for compilers. It covers language specifications, including formal languages, regular expressions, and context-free grammars, as well as syntax analysis techniques such as scanning and parsing. The document also explains concepts like string concatenation, set operations on languages, and the Kleene star and plus operations.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views104 pages

Language Syntax

The document discusses the syntax of programming languages, emphasizing the importance of clearly specified syntax for compilers. It covers language specifications, including formal languages, regular expressions, and context-free grammars, as well as syntax analysis techniques such as scanning and parsing. The document also explains concepts like string concatenation, set operations on languages, and the Kleene star and plus operations.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Programming Language Syntax

Principles of Programming Languages

Nguyễn Thị Minh Huyền

Faculty of Mathematics, Mechanics and Informatics


VNU University of Science, Hanoi
Contents

1. Introduction

2. Language specifications
Formal language
Regular expressions
Context-free grammars

3. Syntax Analysis
Scanning
Deterministic finite automaton
Generating a finite automaton
Scanner code
Parsing

Programming Language Syntax 2 / 48


Introduction

Contents

1. Introduction

2. Language specifications
Formal language
Regular expressions
Context-free grammars

3. Syntax Analysis
Scanning
Deterministic finite automaton
Generating a finite automaton
Scanner code
Parsing

Programming Language Syntax 1 / 48


Introduction

Language syntaxe

Programming languages must have a clearly specified


syntax.
Compilers of a programming language only understand
programs conforming to its syntax specifications.
Language specifications: formal languages
Regular expression (lexical analysis)
Context-free grammar (syntax analysis)

Programming Language Syntax 2 / 48


Introduction

Language syntaxe

Programming languages must have a clearly specified


syntax.
Compilers of a programming language only understand
programs conforming to its syntax specifications.
Language specifications: formal languages
Regular expression (lexical analysis)
Context-free grammar (syntax analysis)

Programming Language Syntax 2 / 48


Introduction

Language syntaxe

Programming languages must have a clearly specified


syntax.
Compilers of a programming language only understand
programs conforming to its syntax specifications.
Language specifications: formal languages
Regular expression (lexical analysis)
Context-free grammar (syntax analysis)

Programming Language Syntax 2 / 48


Introduction

Language syntaxe

Programming languages must have a clearly specified


syntax.
Compilers of a programming language only understand
programs conforming to its syntax specifications.
Language specifications: formal languages
Regular expression (lexical analysis)
Context-free grammar (syntax analysis)

Programming Language Syntax 2 / 48


Introduction

Language syntaxe

Programming languages must have a clearly specified


syntax.
Compilers of a programming language only understand
programs conforming to its syntax specifications.
Language specifications: formal languages
Regular expression (lexical analysis)
Context-free grammar (syntax analysis)

Programming Language Syntax 2 / 48


Introduction

Language syntax (1)

In a natural language:
Alphabet
Word: string of characters in the alphabet
Defined in a dictionary
Categorized in accordance with its syntactic functions
(noun, verb, adjective ...)
Sentence: string of words in the dictionary, in accordance
with the grammar
Constituents: noun phrase, verb phrase, adjective phrase
Paragraph, document...

Programming Language Syntax 3 / 48


Introduction

Language syntax (1)

In a natural language:
Alphabet
Word: string of characters in the alphabet
Defined in a dictionary
Categorized in accordance with its syntactic functions
(noun, verb, adjective ...)
Sentence: string of words in the dictionary, in accordance
with the grammar
Constituents: noun phrase, verb phrase, adjective phrase
Paragraph, document...

Programming Language Syntax 3 / 48


Introduction

Language syntax (1)

In a natural language:
Alphabet
Word: string of characters in the alphabet
Defined in a dictionary
Categorized in accordance with its syntactic functions
(noun, verb, adjective ...)
Sentence: string of words in the dictionary, in accordance
with the grammar
Constituents: noun phrase, verb phrase, adjective phrase
Paragraph, document...

Programming Language Syntax 3 / 48


Introduction

Language syntax (1)

In a natural language:
Alphabet
Word: string of characters in the alphabet
Defined in a dictionary
Categorized in accordance with its syntactic functions
(noun, verb, adjective ...)
Sentence: string of words in the dictionary, in accordance
with the grammar
Constituents: noun phrase, verb phrase, adjective phrase
Paragraph, document...

Programming Language Syntax 3 / 48


Introduction

Language syntax (1)

In a natural language:
Alphabet
Word: string of characters in the alphabet
Defined in a dictionary
Categorized in accordance with its syntactic functions
(noun, verb, adjective ...)
Sentence: string of words in the dictionary, in accordance
with the grammar
Constituents: noun phrase, verb phrase, adjective phrase
Paragraph, document...

Programming Language Syntax 3 / 48


Introduction

Language syntax (2)

In a programing language:
Alphabet: a, ..., z, , ?, <, >, ; (, ), {, }, ...
Token: if, while, =, ==, <= ...
Tokens are specified using string patterns
Statement in accordance with the syntax
Syntax is specified by a formal grammar
Program

Programming Language Syntax 4 / 48


Introduction

Language syntax (2)

In a programing language:
Alphabet: a, ..., z, , ?, <, >, ; (, ), {, }, ...
Token: if, while, =, ==, <= ...
Tokens are specified using string patterns
Statement in accordance with the syntax
Syntax is specified by a formal grammar
Program

Programming Language Syntax 4 / 48


Introduction

Language syntax (2)

In a programing language:
Alphabet: a, ..., z, , ?, <, >, ; (, ), {, }, ...
Token: if, while, =, ==, <= ...
Tokens are specified using string patterns
Statement in accordance with the syntax
Syntax is specified by a formal grammar
Program

Programming Language Syntax 4 / 48


Introduction

Language syntax (2)

In a programing language:
Alphabet: a, ..., z, , ?, <, >, ; (, ), {, }, ...
Token: if, while, =, ==, <= ...
Tokens are specified using string patterns
Statement in accordance with the syntax
Syntax is specified by a formal grammar
Program

Programming Language Syntax 4 / 48


Introduction

Language syntax (2)

In a programing language:
Alphabet: a, ..., z, , ?, <, >, ; (, ), {, }, ...
Token: if, while, =, ==, <= ...
Tokens are specified using string patterns
Statement in accordance with the syntax
Syntax is specified by a formal grammar
Program

Programming Language Syntax 4 / 48


Language specifications

Contents

1. Introduction

2. Language specifications
Formal language
Regular expressions
Context-free grammars

3. Syntax Analysis
Scanning
Deterministic finite automaton
Generating a finite automaton
Scanner code
Parsing

Programming Language Syntax 5 / 48


Language specifications Formal language

Formal language

Alphabet: a finite, nonempty set of symbols


Conventional notation: Σ
A string over an alphabet Σ: a finite sequence of symbols
from Σ
 - empty string: empty sequence of symbols
Σ∗ (the Kleene star of Σ) - set of all strings over Σ, including

A language L over an alphabet Σ: a set of strings over Σ
L is a subset of Σ∗

Programming Language Syntax 6 / 48


Language specifications Formal language

Formal language

Alphabet: a finite, nonempty set of symbols


Conventional notation: Σ
A string over an alphabet Σ: a finite sequence of symbols
from Σ
 - empty string: empty sequence of symbols
Σ∗ (the Kleene star of Σ) - set of all strings over Σ, including

A language L over an alphabet Σ: a set of strings over Σ
L is a subset of Σ∗

Programming Language Syntax 6 / 48


Language specifications Formal language

Formal language

Alphabet: a finite, nonempty set of symbols


Conventional notation: Σ
A string over an alphabet Σ: a finite sequence of symbols
from Σ
 - empty string: empty sequence of symbols
Σ∗ (the Kleene star of Σ) - set of all strings over Σ, including

A language L over an alphabet Σ: a set of strings over Σ
L is a subset of Σ∗

Programming Language Syntax 6 / 48


Language specifications Formal language

Formal language

Alphabet: a finite, nonempty set of symbols


Conventional notation: Σ
A string over an alphabet Σ: a finite sequence of symbols
from Σ
 - empty string: empty sequence of symbols
Σ∗ (the Kleene star of Σ) - set of all strings over Σ, including

A language L over an alphabet Σ: a set of strings over Σ
L is a subset of Σ∗

Programming Language Syntax 6 / 48


Language specifications Formal language

Formal language

Alphabet: a finite, nonempty set of symbols


Conventional notation: Σ
A string over an alphabet Σ: a finite sequence of symbols
from Σ
 - empty string: empty sequence of symbols
Σ∗ (the Kleene star of Σ) - set of all strings over Σ, including

A language L over an alphabet Σ: a set of strings over Σ
L is a subset of Σ∗

Programming Language Syntax 6 / 48


Language specifications Formal language

Formal language

Alphabet: a finite, nonempty set of symbols


Conventional notation: Σ
A string over an alphabet Σ: a finite sequence of symbols
from Σ
 - empty string: empty sequence of symbols
Σ∗ (the Kleene star of Σ) - set of all strings over Σ, including

A language L over an alphabet Σ: a set of strings over Σ
L is a subset of Σ∗

Programming Language Syntax 6 / 48


Language specifications Formal language

String concatenation

Concatenation of two strings u = u1 · · · um and v = v1 · · · vn


(with n, m ≥ 0) over Σ is

w = u · v = uv = u1 · · · um v1 · · · vn

The empty string is the neutral element:

w = w = w ∀w ∈ Σ∗

Powers (exponents):
Denote u 0 = , u 1 = u, u n = u n−1 · u
with n being any natural number > 1

Programming Language Syntax 7 / 48


Language specifications Formal language

String concatenation

Concatenation of two strings u = u1 · · · um and v = v1 · · · vn


(with n, m ≥ 0) over Σ is

w = u · v = uv = u1 · · · um v1 · · · vn

The empty string is the neutral element:

w = w = w ∀w ∈ Σ∗

Powers (exponents):
Denote u 0 = , u 1 = u, u n = u n−1 · u
with n being any natural number > 1

Programming Language Syntax 7 / 48


Language specifications Formal language

String concatenation

Concatenation of two strings u = u1 · · · um and v = v1 · · · vn


(with n, m ≥ 0) over Σ is

w = u · v = uv = u1 · · · um v1 · · · vn

The empty string is the neutral element:

w = w = w ∀w ∈ Σ∗

Powers (exponents):
Denote u 0 = , u 1 = u, u n = u n−1 · u
with n being any natural number > 1

Programming Language Syntax 7 / 48


Language specifications Formal language

Language concatenation

Given L1 , L2 ⊆ Σ∗ , the concatenation of L1 and L2 is

L = L1 · L2 = L1 L2 = {w ∈ Σ∗ |∃u ∈ L1 , v ∈ L2 : w = u · v}

L{} = {}L = L
L∅ = ∅L = ∅
Powers: Given L ⊆ Σ∗
L0 = {}
L1 = L
Ln = Ln−1 L
with n being any natural number > 1

Programming Language Syntax 8 / 48


Language specifications Formal language

Language concatenation

Given L1 , L2 ⊆ Σ∗ , the concatenation of L1 and L2 is

L = L1 · L2 = L1 L2 = {w ∈ Σ∗ |∃u ∈ L1 , v ∈ L2 : w = u · v}

L{} = {}L = L
L∅ = ∅L = ∅
Powers: Given L ⊆ Σ∗
L0 = {}
L1 = L
Ln = Ln−1 L
with n being any natural number > 1

Programming Language Syntax 8 / 48


Language specifications Formal language

Language concatenation

Given L1 , L2 ⊆ Σ∗ , the concatenation of L1 and L2 is

L = L1 · L2 = L1 L2 = {w ∈ Σ∗ |∃u ∈ L1 , v ∈ L2 : w = u · v}

L{} = {}L = L
L∅ = ∅L = ∅
Powers: Given L ⊆ Σ∗
L0 = {}
L1 = L
Ln = Ln−1 L
with n being any natural number > 1

Programming Language Syntax 8 / 48


Language specifications Formal language

Language concatenation

Given L1 , L2 ⊆ Σ∗ , the concatenation of L1 and L2 is

L = L1 · L2 = L1 L2 = {w ∈ Σ∗ |∃u ∈ L1 , v ∈ L2 : w = u · v}

L{} = {}L = L
L∅ = ∅L = ∅
Powers: Given L ⊆ Σ∗
L0 = {}
L1 = L
Ln = Ln−1 L
with n being any natural number > 1

Programming Language Syntax 8 / 48


Language specifications Formal language

Set operations on languages

Union, intersection, difference, complement


Union: L1 , L2 ⊆ Σ∗

L = L1 ∪ L2 = L1 ∨ L2 = {w ∈ Σ∗ |w ∈ L1 ∨ w ∈ L2 }

Programming Language Syntax 9 / 48


Language specifications Formal language

Set operations on languages

Union, intersection, difference, complement


Union: L1 , L2 ⊆ Σ∗

L = L1 ∪ L2 = L1 ∨ L2 = {w ∈ Σ∗ |w ∈ L1 ∨ w ∈ L2 }

Programming Language Syntax 9 / 48


Language specifications Formal language

Kleene star, Kleene plus

Given L ⊆ Σ∗
The Kleene star (or concatenation closure) of L

[

L = Ln
n=0

The Kleene plus of L



[
L+ = Ln
n=1

Example: Σ = {0, 1}
(Σ2 )∗ =?

Programming Language Syntax 10 / 48


Language specifications Formal language

Kleene star, Kleene plus

Given L ⊆ Σ∗
The Kleene star (or concatenation closure) of L

[

L = Ln
n=0

The Kleene plus of L



[
L+ = Ln
n=1

Example: Σ = {0, 1}
(Σ2 )∗ =?

Programming Language Syntax 10 / 48


Language specifications Formal language

Kleene star, Kleene plus

Given L ⊆ Σ∗
The Kleene star (or concatenation closure) of L

[

L = Ln
n=0

The Kleene plus of L



[
L+ = Ln
n=1

Example: Σ = {0, 1}
(Σ2 )∗ =?

Programming Language Syntax 10 / 48


Language specifications Formal language

Kleene star, Kleene plus

Given L ⊆ Σ∗
The Kleene star (or concatenation closure) of L

[

L = Ln
n=0

The Kleene plus of L



[
L+ = Ln
n=1

Example: Σ = {0, 1}
(Σ2 )∗ =?

Programming Language Syntax 10 / 48


Language specifications Formal language

Operator precedence

Unary operators: Kleene star *


Binary operators:
Concatenation
Union

Programming Language Syntax 11 / 48


Language specifications Formal language

Operator precedence

Unary operators: Kleene star *


Binary operators:
Concatenation
Union

Programming Language Syntax 11 / 48


Language specifications Regular expressions

Regular expression

Let Σ be an alphabet. A regular expression (regex) R


defines a language L(R)
Inductive definition:
Basis: a (a ∈ Σ) is a regex representing the language {a}, 
representing {}, ∅ representing the empty language
Inductive step: If R1 , R2 are regular expressions, then
R1 |R2 is a regex defining the language L(R1 ) ∪ L(R2 )
R1 .R2 (or R1 R2 ) is a regex defining the language L(R1 ).L(R2 )
R1∗ defining the language L(R1 )∗
Closure: Nothing else is a regex.
Parentheses: We use parentheses to define the order of
operations, but we often omit them following standard
precedence rules: Star (∗ ) > Concatenation > Union (+)

Programming Language Syntax 12 / 48


Language specifications Regular expressions

Regular expression

Let Σ be an alphabet. A regular expression (regex) R


defines a language L(R)
Inductive definition:
Basis: a (a ∈ Σ) is a regex representing the language {a}, 
representing {}, ∅ representing the empty language
Inductive step: If R1 , R2 are regular expressions, then
R1 |R2 is a regex defining the language L(R1 ) ∪ L(R2 )
R1 .R2 (or R1 R2 ) is a regex defining the language L(R1 ).L(R2 )
R1∗ defining the language L(R1 )∗
Closure: Nothing else is a regex.
Parentheses: We use parentheses to define the order of
operations, but we often omit them following standard
precedence rules: Star (∗ ) > Concatenation > Union (+)

Programming Language Syntax 12 / 48


Language specifications Regular expressions

Tokens: Example

letter = a | b | c | ... | A | B | C | ...


digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
pdigit = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
id = (letter | _)(letter | digit | _)*
num = 0 | pdigit(digit)*

Programming Language Syntax 13 / 48


Language specifications Regular expressions

Tokens: Example

letter = a | b | c | ... | A | B | C | ...


digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
pdigit = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
id = (letter | _)(letter | digit | _)*
num = 0 | pdigit(digit)*

Programming Language Syntax 13 / 48


Language specifications Regular expressions

Tokens: Example

letter = a | b | c | ... | A | B | C | ...


digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
pdigit = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
id = (letter | _)(letter | digit | _)*
num = 0 | pdigit(digit)*

Programming Language Syntax 13 / 48


Language specifications Regular expressions

Tokens: Example

letter = a | b | c | ... | A | B | C | ...


digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
pdigit = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
id = (letter | _)(letter | digit | _)*
num = 0 | pdigit(digit)*

Programming Language Syntax 13 / 48


Language specifications Regular expressions

Tokens: Example

letter = a | b | c | ... | A | B | C | ...


digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
pdigit = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
id = (letter | _)(letter | digit | _)*
num = 0 | pdigit(digit)*

Programming Language Syntax 13 / 48


Language specifications Context-free grammars

Regular expressions for syntax?

Regular expressions are not sufficient to capture all


programming constructs
Regular expressions have no concept of counting, therefore
impossible to create a regular expression R for matching
L(R) = {, (), (()), ((())), · · · }

Programming Language Syntax 14 / 48


Language specifications Context-free grammars

Context-free grammars (CFG)

Formal definition: A CFG is quadruple (4-tuple)


G = (T , N, S, P), in which:
T is an alphabet of terminals
N is an alphabet of nonterminals or variables, N ∩ T = ∅
S ∈ N is a start symbol
P is a finite set of rules/productions A → α
A ∈ N, →∈ / T ∪ N, α ∈ (T ∪ N)∗

Programming Language Syntax 15 / 48


Language specifications Context-free grammars

Context-free grammars (CFG)

Formal definition: A CFG is quadruple (4-tuple)


G = (T , N, S, P), in which:
T is an alphabet of terminals
N is an alphabet of nonterminals or variables, N ∩ T = ∅
S ∈ N is a start symbol
P is a finite set of rules/productions A → α
A ∈ N, →∈ / T ∪ N, α ∈ (T ∪ N)∗

Programming Language Syntax 15 / 48


Language specifications Context-free grammars

Context-free grammars (CFG)

Formal definition: A CFG is quadruple (4-tuple)


G = (T , N, S, P), in which:
T is an alphabet of terminals
N is an alphabet of nonterminals or variables, N ∩ T = ∅
S ∈ N is a start symbol
P is a finite set of rules/productions A → α
A ∈ N, →∈ / T ∪ N, α ∈ (T ∪ N)∗

Programming Language Syntax 15 / 48


Language specifications Context-free grammars

Context-free grammars (CFG)

Formal definition: A CFG is quadruple (4-tuple)


G = (T , N, S, P), in which:
T is an alphabet of terminals
N is an alphabet of nonterminals or variables, N ∩ T = ∅
S ∈ N is a start symbol
P is a finite set of rules/productions A → α
A ∈ N, →∈ / T ∪ N, α ∈ (T ∪ N)∗

Programming Language Syntax 15 / 48


Language specifications Context-free grammars

Context-free grammars (CFG)

Formal definition: A CFG is quadruple (4-tuple)


G = (T , N, S, P), in which:
T is an alphabet of terminals
N is an alphabet of nonterminals or variables, N ∩ T = ∅
S ∈ N is a start symbol
P is a finite set of rules/productions A → α
A ∈ N, →∈ / T ∪ N, α ∈ (T ∪ N)∗

Programming Language Syntax 15 / 48


Language specifications Context-free grammars

Derivation

Direct derivation: α ∈ (T ∪ N)∗ directly generates


β ∈ (T ∪ N)∗ (or β is directly derived from α), denoted
α ⇒ β, iff there exists a rule A → γ ∈ P s.t. α = uAv and
β = uγv.
In other words, the right-hand side is obtained by using a
production to replace some nonterminal in the left-hand side.
The relation ⇒∗ denotes the reflexive transitive closure of
the derivation relation ⇒.
α ⇒∗ β: derives after zero or more replacements
[w0 , w1 , · · · , wn ] - Derivation of n steps w0 ⇒ w1 ⇒ ... ⇒ wn
w0 ⇒ ∗ wn

Programming Language Syntax 16 / 48


Language specifications Context-free grammars

Derivation

Direct derivation: α ∈ (T ∪ N)∗ directly generates


β ∈ (T ∪ N)∗ (or β is directly derived from α), denoted
α ⇒ β, iff there exists a rule A → γ ∈ P s.t. α = uAv and
β = uγv.
In other words, the right-hand side is obtained by using a
production to replace some nonterminal in the left-hand side.
The relation ⇒∗ denotes the reflexive transitive closure of
the derivation relation ⇒.
α ⇒∗ β: derives after zero or more replacements
[w0 , w1 , · · · , wn ] - Derivation of n steps w0 ⇒ w1 ⇒ ... ⇒ wn
w0 ⇒ ∗ wn

Programming Language Syntax 16 / 48


Language specifications Context-free grammars

Derivation

Direct derivation: α ∈ (T ∪ N)∗ directly generates


β ∈ (T ∪ N)∗ (or β is directly derived from α), denoted
α ⇒ β, iff there exists a rule A → γ ∈ P s.t. α = uAv and
β = uγv.
In other words, the right-hand side is obtained by using a
production to replace some nonterminal in the left-hand side.
The relation ⇒∗ denotes the reflexive transitive closure of
the derivation relation ⇒.
α ⇒∗ β: derives after zero or more replacements
[w0 , w1 , · · · , wn ] - Derivation of n steps w0 ⇒ w1 ⇒ ... ⇒ wn
w0 ⇒ ∗ wn

Programming Language Syntax 16 / 48


Language specifications Context-free grammars

Language generated by a grammar

Let G = (T , N, S, P) be a grammar. The formal language L


generated by the grammar G is the set of all strings over
the alphabet T derived from the start symbol S:
L(G) = {w ∈ T ∗ |S ⇒∗ w}
Two formal grammars G1 and G2 are equivalent iff
L(G1 ) = L(G2 ).

Programming Language Syntax 17 / 48


Language specifications Context-free grammars

Language generated by a grammar

Let G = (T , N, S, P) be a grammar. The formal language L


generated by the grammar G is the set of all strings over
the alphabet T derived from the start symbol S:
L(G) = {w ∈ T ∗ |S ⇒∗ w}
Two formal grammars G1 and G2 are equivalent iff
L(G1 ) = L(G2 ).

Programming Language Syntax 17 / 48


Language specifications Context-free grammars

Example

Expression grammar with precedence and associativity


expr → id | num | −expr | (expr ) | expr op expr
op → + | - | * | /
In this grammar, generate the string slope * x +
intercept

Programming Language Syntax 18 / 48


Language specifications Context-free grammars

Example

expr ⇒ expr op expr


⇒ expr op id
⇒ expr + id
⇒ expr op expr + id
⇒ expr op id + id
⇒ expr * id + id
⇒ id * id + id
(slope) (x) (intercept)

Programming Language Syntax 19 / 48


Language specifications Context-free grammars

Parse tree

Each derivation [w0 , w1 , · · · , wn ] s.t. w0 = A ∈ N can be


represented by a parse tree
Each symbol (terminal or nonterminal) is a node in the tree
The constituents on the right-hand side of the production
used to replace the symbol are its children
If w0 is the start symbol S, each string wi (1 ≤ i ≤ n) is
called a sentential form.
If wn is the final sentential form, i.e. it consists of only
terminals, then wn is called the yield of the derivation.
Parse tree of the above derivation?

Programming Language Syntax 20 / 48


Language specifications Context-free grammars

Parse tree

Each derivation [w0 , w1 , · · · , wn ] s.t. w0 = A ∈ N can be


represented by a parse tree
Each symbol (terminal or nonterminal) is a node in the tree
The constituents on the right-hand side of the production
used to replace the symbol are its children
If w0 is the start symbol S, each string wi (1 ≤ i ≤ n) is
called a sentential form.
If wn is the final sentential form, i.e. it consists of only
terminals, then wn is called the yield of the derivation.
Parse tree of the above derivation?

Programming Language Syntax 20 / 48


Language specifications Context-free grammars

Parse tree

Each derivation [w0 , w1 , · · · , wn ] s.t. w0 = A ∈ N can be


represented by a parse tree
Each symbol (terminal or nonterminal) is a node in the tree
The constituents on the right-hand side of the production
used to replace the symbol are its children
If w0 is the start symbol S, each string wi (1 ≤ i ≤ n) is
called a sentential form.
If wn is the final sentential form, i.e. it consists of only
terminals, then wn is called the yield of the derivation.
Parse tree of the above derivation?

Programming Language Syntax 20 / 48


Language specifications Context-free grammars

Example

Parse tree for "slope * x + intercept"

Programming Language Syntax 21 / 48


Language specifications Context-free grammars

Left-most and right-most derivations

A derivation is a series of replacements


Right-most derivation: At each step, the right-most
nonterminal is replaced with the right-hand side of some
production
Left-most derivation: At each step, the left-most
nonterminal is replaced with the right-hand side of some
production
Left-most derivation equivalent to the previous right-most
derivation?
The parse tree does not depend on the replacement
strategy

Programming Language Syntax 22 / 48


Language specifications Context-free grammars

Left-most and right-most derivations

A derivation is a series of replacements


Right-most derivation: At each step, the right-most
nonterminal is replaced with the right-hand side of some
production
Left-most derivation: At each step, the left-most
nonterminal is replaced with the right-hand side of some
production
Left-most derivation equivalent to the previous right-most
derivation?
The parse tree does not depend on the replacement
strategy

Programming Language Syntax 22 / 48


Language specifications Context-free grammars

Left-most and right-most derivations

A derivation is a series of replacements


Right-most derivation: At each step, the right-most
nonterminal is replaced with the right-hand side of some
production
Left-most derivation: At each step, the left-most
nonterminal is replaced with the right-hand side of some
production
Left-most derivation equivalent to the previous right-most
derivation?
The parse tree does not depend on the replacement
strategy

Programming Language Syntax 22 / 48


Language specifications Context-free grammars

Left-most and right-most derivations

A derivation is a series of replacements


Right-most derivation: At each step, the right-most
nonterminal is replaced with the right-hand side of some
production
Left-most derivation: At each step, the left-most
nonterminal is replaced with the right-hand side of some
production
Left-most derivation equivalent to the previous right-most
derivation?
The parse tree does not depend on the replacement
strategy

Programming Language Syntax 22 / 48


Language specifications Context-free grammars

Left-most and right-most derivations

A derivation is a series of replacements


Right-most derivation: At each step, the right-most
nonterminal is replaced with the right-hand side of some
production
Left-most derivation: At each step, the left-most
nonterminal is replaced with the right-hand side of some
production
Left-most derivation equivalent to the previous right-most
derivation?
The parse tree does not depend on the replacement
strategy

Programming Language Syntax 22 / 48


Language specifications Context-free grammars

Example

The grammar is ambiguous: Alternate (incorrect) parse tree for


"slope * x + intercept"

Programming Language Syntax 23 / 48


Language specifications Context-free grammars

Example

Better version: unambiguous and captures precedence


expr → term | expr add_op term
term → factor | term mult_op factor
factor → id | num | −factor | (expr )
add_op → + | -
mult_op → * | /

Programming Language Syntax 24 / 48


Language specifications Context-free grammars

Example

Parse tree for expression grammar (with left associativity) for


3+4*5

Programming Language Syntax 25 / 48


Language specifications Context-free grammars

Common syntax of RE
A single ordinary character represents itself, excepting
metacharacters: ? + - * . { } [ ] ( ) \ | ˆ $
To match a metacharacter, use \ before.
[03a−c] ≡ {0, 3, a, b, c}, [ˆ 15] ≡ set of all characters
excepting 1 and 5
. replaces any character, ˆ and $ match start and end of a
line string.
\< and \> match empty string at the beginning and the end
of a word, \b matches empty string at the edge of a word,
\B matches empty string not at the edge of a word.
Repetition: ?, *, +, {n}, {n, }, {n, m}
Concatenation, union |
\n substring between the n-th () from the beginning to that
position.
Programming Language Syntax 26 / 48
Syntax Analysis

Contents

1. Introduction

2. Language specifications
Formal language
Regular expressions
Context-free grammars

3. Syntax Analysis
Scanning
Deterministic finite automaton
Generating a finite automaton
Scanner code
Parsing

Programming Language Syntax 27 / 48


Syntax Analysis Scanning

Scanning

Scanner is responsible for


tokenizing source;
removing comments;
dealing with pragmas/directives (i.e., significant
comments);
saving text of identifiers, numbers, strings;
saving source locations (file, line, column) for error
messages.

Programming Language Syntax 28 / 48


Syntax Analysis Scanning

Scanning: Example

Scan for id and num:


Read the characters in the source program one at a time
with look-ahead
If it is a letter or an underscore, we keep reading letters and
digits and maybe underscores until we can’t anymore
then we check to see if it is a reserved word
If it is a positive digit, we keep reading until we find a
non-digit

Programming Language Syntax 29 / 48


Syntax Analysis Scanning

Scanning: Example

Scan for id and num:


Read the characters in the source program one at a time
with look-ahead
If it is a letter or an underscore, we keep reading letters and
digits and maybe underscores until we can’t anymore
then we check to see if it is a reserved word
If it is a positive digit, we keep reading until we find a
non-digit

Programming Language Syntax 29 / 48


Syntax Analysis Scanning

Scanning: Example

Scan for id and num:


Read the characters in the source program one at a time
with look-ahead
If it is a letter or an underscore, we keep reading letters and
digits and maybe underscores until we can’t anymore
then we check to see if it is a reserved word
If it is a positive digit, we keep reading until we find a
non-digit

Programming Language Syntax 29 / 48


Syntax Analysis Scanning

Scanning: Example

Scan for id and num:


Read the characters in the source program one at a time
with look-ahead
If it is a letter or an underscore, we keep reading letters and
digits and maybe underscores until we can’t anymore
then we check to see if it is a reserved word
If it is a positive digit, we keep reading until we find a
non-digit

Programming Language Syntax 29 / 48


Syntax Analysis Scanning

Scanning: Example

Scan for id and num:


Read the characters in the source program one at a time
with look-ahead
If it is a letter or an underscore, we keep reading letters and
digits and maybe underscores until we can’t anymore
then we check to see if it is a reserved word
If it is a positive digit, we keep reading until we find a
non-digit

Programming Language Syntax 29 / 48


Syntax Analysis Scanning

Scanning: Another example

Tokens
assign → :=
plus → +
minus → -
times → *
div → /
lparen → (
rparen → )
id → letter(letter | digit)∗
except for read and write
number → digit digit∗ | digit∗ ( . digit | digit . ) digit∗
comment → /* (non-* | * non-/)∗ *+ /
| // (non-newline)∗ newline

Programming Language Syntax 30 / 48


Syntax Analysis Scanning

Scanner: pseudo-code

Programming Language Syntax 31 / 48


Syntax Analysis Scanning

Scanning: finite automaton

Programming Language Syntax 32 / 48


Syntax Analysis Scanning

Deterministic finite automaton (DFA)

A machine that accepts the language


We run the machine over and over to get one token after
another
Longest matching prefix rule (nearly universal):
Always take the longest possible token from the input
Example: 3.14159 is a real const and never 3, ., and 14159
Regular expressions "generate" a regular language; DFAs
"recognize" it

Programming Language Syntax 33 / 48


Syntax Analysis Scanning

Deterministic finite automata : Formal definition

A DFA is a 5-tuple A = (S, Σ, δ, s0 , F ), where


S is a finite set of states, S 6= ∅
Σ 6= ∅ is a finite set of input symbols
s0 ∈ S is a start state
F ⊆ S is a set of final states
δ : S × Σ → S is a transition function that takes as
arguments a state and an input symbol and returns a state.
δ(p, a) = q : the DFA is in the state p, given the input symbol
a, it enters the state q.
δ is usually represented by a transition table.

Programming Language Syntax 34 / 48


Syntax Analysis Scanning

Representation of DFA

Transition diagram
Each state is a node. Start state is marked by an arrow into
it, each accepting state (final state) is marked by a double
circle.
For each state p ∈ S and each input symbol a, if δ(p, a) = q
then the transition diagram has an arc from p to q, labeled
a.

1 1
0
s1 s2
0
Programming Language Syntax 35 / 48
Syntax Analysis Scanning

Generating a finite automaton

DFAs can be generated automatically from a set of regular


expressions
Section 2.2.1, pages 56-61 (Scott textbook)
Convert a regular expression to a NFA (non-deterministic
finite automaton)
Base case: Transition diagram of {a}, {}, ∅?
Operations: union, concatenation, Kleene *
Convert a NFA to a DFA
Minimizing the DFA

Programming Language Syntax 36 / 48


Syntax Analysis Scanning

Generating a finite automaton

DFAs can be generated automatically from a set of regular


expressions
Section 2.2.1, pages 56-61 (Scott textbook)
Convert a regular expression to a NFA (non-deterministic
finite automaton)
Base case: Transition diagram of {a}, {}, ∅?
Operations: union, concatenation, Kleene *
Convert a NFA to a DFA
Minimizing the DFA

Programming Language Syntax 36 / 48


Syntax Analysis Scanning

Generating a finite automaton

DFAs can be generated automatically from a set of regular


expressions
Section 2.2.1, pages 56-61 (Scott textbook)
Convert a regular expression to a NFA (non-deterministic
finite automaton)
Base case: Transition diagram of {a}, {}, ∅?
Operations: union, concatenation, Kleene *
Convert a NFA to a DFA
Minimizing the DFA

Programming Language Syntax 36 / 48


Syntax Analysis Scanning

Generating a finite automaton

DFAs can be generated automatically from a set of regular


expressions
Section 2.2.1, pages 56-61 (Scott textbook)
Convert a regular expression to a NFA (non-deterministic
finite automaton)
Base case: Transition diagram of {a}, {}, ∅?
Operations: union, concatenation, Kleene *
Convert a NFA to a DFA
Minimizing the DFA

Programming Language Syntax 36 / 48


Syntax Analysis Scanning

From a regular expression to an NFA


Construction of NFA equivalent to an regular expression

Programming Language Syntax 37 / 48


Syntax Analysis Scanning

From a regular expression to an NFA (cont.)

Each step of subconstruction needs to preserve 3 invariants


No transitions into the initial state
A single final state
No transitions out of the final state

Programming Language Syntax 38 / 48


Syntax Analysis Scanning

From a regular expression to an NFA: Example


NFA equivalent to d ∗ ( . d | d . ) d ∗

Programming Language Syntax 39 / 48


Syntax Analysis Scanning

From an NFA to a DFA

Implementation of NFA: explore all possible transitions


concurrently or via backtracking
⇒ complex and time-consuming
Transform the NFA into an equivalent DFA
Each state of the DFA is a set of states that the NFA might
reached on the same input

Programming Language Syntax 40 / 48


Syntax Analysis Scanning

From an NFA to a DFA: Example

Programming Language Syntax 41 / 48


Syntax Analysis Scanning

Minimizing the DFA

Reduce the space complexity

P ← {F , S\F }
repeat
done ← true
for Q ∈ P
for si , sj ∈ Q, si 6= sj
for a ∈ Σ
if δ(si , a) 6≡P δ(sj , a)
done ← false
Refine Q based on a
until done;

Programming Language Syntax 42 / 48


Syntax Analysis Scanning

Minimizing the DFA: Example

Programming Language Syntax 43 / 48


Syntax Analysis Scanning

Three ways to build scanners

Ad-hoc scanners: create manually code in some


implementation language (slide 31). This generally yields
the fastest, most compact code by doing lots of
special-purpose things
Writing a pure DFA as a set of nested case statements
(Section 2.2.2, pages 61-65, Scott’s textbook)
Table-driven DFA (Section 2.2.3, pages 65-67, Scott’s
textbook) - method used in the tool lex (or flex)

Programming Language Syntax 44 / 48


Syntax Analysis Scanning

Three ways to build scanners

Ad-hoc scanners: create manually code in some


implementation language (slide 31). This generally yields
the fastest, most compact code by doing lots of
special-purpose things
Writing a pure DFA as a set of nested case statements
(Section 2.2.2, pages 61-65, Scott’s textbook)
Table-driven DFA (Section 2.2.3, pages 65-67, Scott’s
textbook) - method used in the tool lex (or flex)

Programming Language Syntax 44 / 48


Syntax Analysis Scanning

Three ways to build scanners

Ad-hoc scanners: create manually code in some


implementation language (slide 31). This generally yields
the fastest, most compact code by doing lots of
special-purpose things
Writing a pure DFA as a set of nested case statements
(Section 2.2.2, pages 61-65, Scott’s textbook)
Table-driven DFA (Section 2.2.3, pages 65-67, Scott’s
textbook) - method used in the tool lex (or flex)

Programming Language Syntax 44 / 48


Syntax Analysis Scanning

Nested case statements

Programming Language Syntax 45 / 48


Syntax Analysis Scanning

Table-driven Scanning

States are numbered as in slide 32 + two states—17 and 18—to "recognize" white space and comments. The

right-hand column represents token state. Numbers in the table indicate an entry for which the corresponding action

is move. Dashes appear where there is no way to extend the current token: if the corresponding entry in token

column is nonempty, then action is recognize; otherwise, action is error.


Programming Language Syntax 46 / 48
Syntax Analysis Scanning

Longest-possible tokens
Longest-possible tokens means you return only when the
next character can’t be used to continue the current token
the next character will generally need to be saved for the
next token
In some cases, you may need to peek at more than one
character of look-ahead in order to know whether to
proceed
For example, in Pascal, when you have a 3 and you see a
dot: do you proceed (3.14) or stop (3..5)?
In messier cases, you may not be able to get by with any
fixed amount of look-ahead
For example, in Fortran
DO 5 I = 1,25 loop
DO 5 I = 1.25 assignment
Here, we need to remember we were in a potentially final
state, and save enough information that we can back up to
it, if we get stuck later
Programming Language Syntax 47 / 48
Syntax Analysis Parsing

Parsing

Terminology:
context-free grammar (CFG)
symbols
terminals (tokens)
non-terminals
production
derivations (left-most and right-most - canonical)
parse trees
sentential form: any string derived from the start symbol

to be continued ...

Programming Language Syntax 48 / 48

You might also like