Chapter 03
Chapter 03
<var> - <subexp>
b <var>
G2: <subexp> ::= <var> - <subexp> | <var>
<var> ::= a | b | c c
<var> b
(a-b)-c
a
Karadeniz Teknik Üniversitesi Chapter Three Programming Languages 3
Why Parse Trees Matter
• We want the structure of the parse tree to
correspond to the semantics of the string it
generates
• This makes grammar design much harder:
we’re interested in the structure of each parse
tree, not just in the generated string
• Parse trees are where syntax meets semantics
a b b c
Karadeniz Teknik Üniversitesi Chapter Three Programming Languages 11
Operator Precedence
• Applies when the order of evaluation is not
completely decided by parentheses
• Each operator has a precedence level, and those
with higher precedence are performed before those
with lower precedence, as if parenthesized
• Most languages put * at a higher precedence level
than +, so that:
a+b*c = a+(b*c)
a <mulexp> * <mulexp>
b c
Karadeniz Teknik Üniversitesi Chapter Three Programming Languages 15
Parse G5: <exp> ::= <exp> + <exp> | <mulexp>
<mulexp> ::= <mulexp> * <mulexp>
| (<exp>)
| a | b | c
a + b * c
<exp>
<exp> = <exp> + <exp>
= <exp> + <mulexp>
= <mulexp> + <mulexp>
<exp> + <exp>
= a + <mulexp> <mulexp> <mulexp>
= a + <mulexp> * <mulexp>
=a+ b * c a <mulexp> * <mulexp>
b c
Our grammar G5 generates both these trees for a+b+c. The first
one is not the usual convention for operator associativity.
G5: <exp> ::= <exp> + <exp> | <mulexp>
<mulexp> ::= <mulexp> * <mulexp>
| (<exp>)
| a | b | c
Karadeniz Teknik Üniversitesi Chapter Three Programming Languages 19
Operator Associativity
• Applies when the order of evaluation is not
decided by parentheses or by precedence
• Left-associative operators group left to
right: a+b+c+d = ((a+b)+c)+d
• Right-associative operators group right to
left: a+b+c+d = a+(b+(c+d))
• Most operators in most languages are left-
associative, but there are exceptions
• ML
3-2-1 — most operators are left-associative
1::2::nil — right-associative (list builder)
• Fortran
a/b*c — most operators are left-associative
a**b**c — right-associative (exponentiation)
and the next slide shows two different parse trees for it...
e1 <if-stmt> s2 Ambiguous
if <exp> then <stmt>
if-then-else
e2 s1 parse trees
if e1 then (if e2 then s1 else s2)
<if-stmt>
e2 s1 s2
Eliminating The Ambiguity
<stmt> ::= <if-stmt> | s1 | s2
<if-stmt> ::= if <expr> then <stmt> else <stmt>
| if <expr> then <stmt>
<expr> ::= e1 | e2
•We want to insist that if this expands into an if, that if must
already have its own else.
•First, we make a new non-terminal <full-stmt> that generates
everything <stmt> generates.
•Except that it can not generate if statements with no else:
<stmt> = <if-stmt>
= if <expr> then <stmt>
= if <expr> then <if-stmt>
= if <expr> then if <expr> then <full-stmt> else <stmt>
= if e1 then if <expr> then <full-stmt> else <stmt>
= if e1 then if e2 then <full-stmt> else <stmt>
= if e1 then if e2 then s1 else <stmt>
= if e1 then if e2 then s1 else s2
e2 s1 s2
Karadeniz Teknik Üniversitesi Chapter Three Programming Languages 33
<full-stmt> ::= if <expr> then <full-stmt> else <full-stmt> |
Parse
Correct
Parse
Tree
s1 | s2 | s3
<stmt> ::= <if-stmt> | s1 | s2 | s3
<if-stmt> ::= if <expr> then <full-stmt> else <stmt> |
if <expr> then <stmt>
<expr> ::= e1 | e2
if e1 then if e2 then s1 else s2 else s3
<if-stmt>
e2 s1 s2
s1 | s2 | s3
<stmt> ::= if <expr> then <full> else <stmt> |
if <expr> then <stmt> |
s1 | s2 | s3
<expr> ::= e1 | e2
1. if e1 then s1
2. if e1 then if e2 then s1
3. if e1 then if e2 then s1 else s2
4. if e1 then if e2 then s1 else s2 else s3
5. if e1 then s1 else if e2 then s1 else s2
int a=0;
if (0==0) Better: correct indentation
if (0==1) a=1;
else a=2;
int a=0;
if (0==0) {
Even better: use of a block
if (0==1) a=1;
reinforces the structure
else a=2;
}
<exp> + <mulexp>
a
+ c
Abstract Syntax Tree
a b
<rootexp> <rootexp> 3
1 2
Karadeniz Teknik Üniversitesi Chapter Three Programming Languages 53
Abstract Syntax Tree: 1-2*3+4
<exp>
parse tree
<exp> + <mulexp>
<rootexp> <rootexp> 3
+
1 2
- 4
<rootexp> <rootexp> 3
1 2
/* yacc definitions */
%%
/* production rules semantic actions (in C)*/
line : exp ';' '\n' { printf ("result is %d\n", $1); }
;
exp : term { $$ = $1; }
| exp '+' term { $$ = $1 + $3; }
| exp '-' term { $$ = $1 - $3; }
;
term : factor { $$ = $1; }
| term '*' factor { $$ = $1 * $3; }
| term '/' factor { $$ = $1 / $3; }
;
factor : number { $$ = $1; }
| '(' exp ')' { $$ = $2; }
;
%% /* C code */
%%
line : exp ';' {printf ("result is %d\n", $1);}
;
%%
%%