Documente Academic
Documente Profesional
Documente Cultură
CSCI 3136 Principles of Programming Languages Faculty of Computer Science Dalhousie University Winter 2012 Reading: Chapter 4
Motivation
Source program (character stream) Front end Scanner (lexical analysis) Token stream Parser (syntactic analysis) Parse tree Symbol table Semantic analysis and code generation Machine-independent code improvement Back end Modied intermediate form Target code generation Target language (e.g., assembly) Abstract syntax tree or other intermediate form
Syntax Describes form of a valid program Can be described by a context-free grammar Semantics Describes meaning of a program Cannot be be described by a context-free grammar Some constraints that may appear syntactic are enforced by semantic analysis: E.g., use of identier only after its declaration
Semantic Analysis
Enforces semantic rules Builds intermediate representation (e.g., abstract syntax tree) Fills symbol table Passes results to intermediate code generator Two approaches Interleaved with syntactic analysis As a separate phase Formal mechanism: Attributes grammars
Static semantic rules Enforced by compiler at compile time Example: Do not use undeclared variable Dynamic semantic rules Compiler generates code for enforcement at run time Examples: division by zero, array index out of bounds Some compilers allow these checks to be disabled
Attribute Grammars
An attribute grammar is an augmented context-free grammar: Each symbol in a production has a number of attributes. Each production is augmented with semantic rules that Copy attribute values between symbols, Evaluate attribute values using semantic functions, Enforce constraints on attribute values.
E1 E2 + T E1 E2 - T ET T1 T2 * F T1 T2 / F TF F1 - F2 F ( E ) F const
E1 .val := sum(E2 .val, T.val) E1 .val := difference(E2 .val, T.val) E.val := T.val T1 .val := product(T2 .val, F.val) T1 .val := quotient(T2 .val, F.val) T.val := F.val F1 .val := negate(F2 .val) F.val := E.val F.val := const.val
Input: aaabbbccc
Parse tree A A A
S B C
a a
B
b b
C
c c
Input: aaabbbccc
Parse tree 3 A A 2 A 1
S 3=3=3 B 3 C 3 C 2 C 1
B 2 B 1
Input: aaabbccc
Parse tree A A A
S B C
a a
b
C
c c
Input: aaabbccc
Parse tree 3 A A 2 A 1
S 3=2=3 B 2 C 3 C 2 C 1
B 1
Inherited attributes: Attributes ow from left to right (from LHS to RHS and from symbols of RHS to symbols of RHS further to the right). S ABC Aa A1 A2 a Bb B1 B2 b C c C1 C2 c B.inhCount := A.count; C.inhCount := A.count A.count := 1 A1 .count := A2 .count + 1 Condition: B.inhCount = 1 B2 .inhCount := B1 .inhCount 1 Condition: C.inhCount := 1 C2 .inhCount := C1 .inhCount 1
Input: aaabbbccc
Parse tree A A A
S B C
a a
B
b b
C
c c
Input: aaabbbccc
Parse tree 3 A A 2 A 1
S B 3 C 3 C 2 C 1=1
B 2 B 1=1
b b
c c
Input: aaabbccc
Parse tree A A A
S B C
a a
b
C
c c
Input: aaabbccc
Parse tree 3 A A 2 A 1
S B 3 C 3
B 2=1
C 2 C 1=1
c c
Attribute Flow
Annotation or decoration of parse tree Process of evaluating attributes Synthesized attributes Attributes of LHS of a production are computed from attributes of the symbols in its RHS. Attributes ow bottom-up in the parse tree. Inherited attributes Attributes for symbols in RHS are computed from attributes of LHS and symbols in RHS preceding them. Attributes ow top-down in the parse tree.
10
10
This grammar captures left-associativity.
5 5
3 3
10 10
This grammar captures left-associativity.
5 5
3 3
10 10
This grammar captures left-associativity. It is not LL(1).
{n} E TE $ E2 .op := A.fun(E1E T.val); E1 .val{$} E2 .val .op, := {+, -} E AT E {n} T n {+} A+ {-} A-
{n} E TE $ E2 .op := A.fun(E1E T.val); E1 .val{$} E2 .val .op, := {+, -} E AT E {n} T n {+} A+ {-} AE
E A T E A T
10
5
Semantic Analysis CSCI 3136: Principles of Programming Languages
10 E 12
A sub T 3
10 10
7 E 12
A add T 5
3 3
12 E 12
5 5
Semantic Analysis CSCI 3136: Principles of Programming Languages
Action Routines
Action routines are instructions for ad-hoc translation interleaved with parsing. Parser generators allow programmers to specify action routines in the grammar. Action routines can appear anywhere in a rule (as long as the grammar is LL(1)). Example E1 A T { E2 .op = A.fun(E1 .op, T.val) } E2 { E1 .val = E2 .val } Action routines are supported, for example, in yacc and bison.