1 / 36

Compiler Construction Principles & Implementation Techniques

Compiler Construction Principles & Implementation Techniques. Dr. Zheng Xiaojuan Associate Professor Software College of Northeast Normal University April. 2008. Knowledge Relation Graph. Top-down. using. Syntax definition. Context Free Grammar. implement. basing on. Bottom-up.

nasnan
Télécharger la présentation

Compiler Construction Principles & Implementation Techniques

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Compiler Construction Principles & Implementation Techniques Dr. Zheng Xiaojuan Associate Professor Software College of Northeast Normal University April. 2008

  2. Knowledge Relation Graph Top-down using Syntax definition Context Free Grammar implement basing on Bottom-up Develop a Parser

  3. § 3 Context Free Grammar & Parsing 3.1 The Parsing Process (语法分析过程) 3.2 Context-free Grammars (上下文无关文法) 3.3 Parse Trees and Abstract Syntax Tree (语法分析树和抽象语法树) 3.4 Ambiguous (二义性) 3.5 Syntax of Sample Language (简单语言的语法)

  4. §4 Top-down Parsing 4.1 Overview of Top-down Parsing 4.2 Three Important Sets 4.3 Left Recursion Removal & Left Factoring 4.4 Recursive-Descent Parsing 4.5 LL(1) Parsing

  5. 4.1 Overview of Top-down Parsing • Problem: • Given CFG definition of the Syntax; • Check whether a program is of well defined structure; • Generate parse tree of the program; • Main Idea • Read sequence of tokens (source program); • Start from the start symbol; • Try to find a proper sequence of derivations, resulting in the sequence of token of the source program;

  6. Example P: (1) Z  aBd (2) B  d (3) B  c (4) B  bB a b c d

  7. 4.1 Overview of Top-down Parsing • Key problem: • According to rest token sequence and the first non-terminal symbol, how to select a right production to make next derivation? • Look ahead how many tokens? • Current token (look ahead one token) • Calculate Predict set for a production A  • {a | S + A     +  a ’}, where VT*, S is start symbol.

  8. How to calculate the predict set for each production?

  9. 4.2 Three Important Sets • First Set(first集) for a string  with non-terminal and terminal symbols; • First() • Follow Set(follow集) for a non-terminal symbol A; • Follow(A) • Predict Set(预测集) for a production; • Predict(A )

  10. First Set (first集) • Definition: • First() = {a | *a, aVT}, • if * then First()= First()  {} • How to calculate First()? •  = , First() = {} •  = a, aVT, First() = {a} •  = A, AVN, First() =First(A) •  = X1 X2 …… Xi-1 Xi …… Xn

  11. For each symbol X, calculate First(X) • S = {A | A * , AVN} • For each terminal symbol a, First(a) = {a} • VN={A1, …, An} , calculate First(Ai) • 初始化, First(Ai) ={}; • for i =1 to n 对于Ai的每个产生式, - if Ai, First(Ai) = First(Ai)  {}; - if AiY1 …. Ym, {Y1 ,…. ,Ym}S, First(Ai) = First(Ai)  First(Y1)  …..  First(Ym) - if AiY1 …. Ym, {Y1 ,…. ,Yj-1}S, Yj  S First(Ai) = {First(Ai)  {First(Y1)  …..  First(Yj-1)-{}}  First(Yj) (3) Repeat (2) until 每个First(Ai)没有变化(收敛).

  12. Example S = {E’, T’} P: (1) E  TE’ (2) E’ + TE’ (3) E’  (4) T  FT’ (5) T’ * F T’ (6) T’  (7) F  (E) (8) F  i (9) F  n

  13. For a string , calculate First() • S = {A | A * , AVN} • For each terminal symbol a, First(a) = {a} • For each non-terminal symbol A, First(A) •  = X1 X2 …… Xi-1 Xi …… Xn - if {X1 ,…. ,Xn}S, First() = First(Ai)  First(Y1)  …..  First(Ym) - if {X1 ,…. ,Xi-1}S, YiS First() = First(Ai)  {First(Y1)  …..  First(Yj-1)-{}}  First(Yj)

  14. Example P: (1) E  TE’ (2) E’ + TE’ (3) E’  (4) T  FT’ (5) T’ * F T’ (6) T’  (7) F  (E) (8) F  i (9) F  n First(E’T’E) = First(T’E’) =

  15. 4.2 Three Important Sets • First Set(first集) for a string  with non-terminal and terminal symbols; • First() • Follow Set(follow集) for a non-terminal symbol A; • Follow(A) • Predict Set(预测集) for a production; • Predict(A ) 

  16. Follow Set (follow集) • Definition: • Follow(A) = {a | S +…Aa…, aVT}, • if S+ …A, then Follow(A)= Follow(A)  {#} • # represents the end of the string

  17. Follow Set (follow集) • How to calculate Follow(A), AVN (1)初始化, AVN, Follow(A) = { } (2)Follow(S) = {#} (3)对于每个产生式A  • If there is no non-terminal symbol in , skip; • If  = B, BVN, Follow(B) = Follow(B)  (First()-{}) • If First(), Follow(B) = Follow(B)  Follow(A) • If  = B, Follow(B) = Follow(B)  Follow(A) (4) Repeat (3) until all follow sets do not change any more;

  18. Example P: (1) E  TE’ (2) E’ + TE’ (3) E’  (4) T  FT’ (5) T’ * F T’ (6) T’  (7) F  (E) (8) F  i (9) F  n

  19. 4.2 Three Important Sets • First Set(first集) for a string  with non-terminal and terminal symbols; • First() • Follow Set(follow集) for a non-terminal symbol A; • Follow(A) • Predict Set(预测集) for a production; • Predict(A )  

  20. Predict Set (predict集) • Definition: • Predict(A  ) = first(), if   first(); • Predict(A  ) = (first()- )  follow(A), if   first();

  21. first集 Example P: (1) E  TE’ (2) E’ + TE’ (3) E’  (4) T  FT’ (5) T’* F T’ (6) T’  (7) F  (E) (8) F  i (9) F  n First(TE’)={i, n,( } First(+TE’)={+} Follow(E’)={#, )} follow集 First(FT’)={i,n,( } First(*FT’)={*} Follow(T’)={ ),+, # } First((E))={ ( } First(i)={i} First(n)={n}

  22. Top-down parsing • Precondition for Top-down parsing (look ahead one symbol) 自顶向下语法分析方法的前提条件 • G = (VT, VN, S, P) • For any A VN, • For any two productions of A, • Predict(A  1) Predict(A  2) =  (同一个非终极符的任意两个产生式的predict集合互不相交) • 这个条件保证:针对当前的符号和当前的非终极符,可以选择唯一的产生式来进行推导;

  23. Example P: (1) Z  aBd {a} (2) B  d {d} (3) B  c {c} (4) B  bB {b} a b c d

  24. Knowledge Relation Graph using Syntax definition CFG check precondition first() basing on Predict(A) Yes Top-down parsing follow(A) Recursive-descent Implement LL(1)

  25. 4.3 Left Recursion Removal & Left Factoring • 消除左递归 • 直接左递归 • 间接左递归 • 消除公共前缀 • 提取公共前缀

  26. 4.4 Recursive-Descent Parsing • Main Idea: • For each non-terminal symbol, generate one parsing sub-routine(语法分析子过程) according to its productions; • 递归下降法: • 针对满足分析条件的CFG; • “递归”:由于产生式的递归导致分析子程序的递归; • “下降”:自顶向下分析; • Disadvantages: • Restriction on CFG is too strict; • inefficient because of too many function calls;

  27. 4.4 Recursive-Descent Parsing • The goal of parsing • Check whether the input string belongs to the language of CFG; • Two actions • match(a): to check current symbol, if match, read next symbol; • Derivation: select the production

  28. Example Z ( ) { if token = a {match(a); B( ); match(d); } else error( ); } B ( ) { case token of d: match(d);break; c: match(c); break; b:{ match(b); B( ); break;} other: error( ); } P: (1) Z  aBd {a} (2) B  d {d} (3) B  c {c} (4) B  bB {b} a b c d main( ){ read(token); Z( )}

  29. General Process • For each A  VN, • A  1|……| n A( ) { case token of Predict(A  1): SubR(1) ; break; …… Predict(A  n): SubR(n) ; break; other: error; } • G = (VT, VN, S, P) • Predefined function: void match(a: VT) • Global variable: token: VT • Input string: str

  30. General Process SubR(): • = X1 X2 …… Xn If Xi VT, match(Xi) If Xi VN, Xi(); void match(a: VT) { if token == a token = readNext(str); else error(); } SubR(): • =  { }

  31. Some Notes • Not real parsing program, but algorithm; • More detailed issues need to be considered • Dealing with errors • Building parse tree How to deal with these issues?

  32. Building Parse Tree • Data structure • ParseTree • Operations • ParseTree BuildRoot(symbol: VT); • ParseTree BuildOneNode(symbol: VT VN) • AddOneSon(father:*ParseTree, son:*ParseTree ) • SetNum(Node:*ParseTree, n:int) 符号 儿子个数 儿子指针

  33. Example Z ( ) { if token = a { match(a); B( ); match(d); } else {error(); return nil;} } *ParseTree SetNum(T, 3); T = BuildRoot(Z); A = BuildOneSon(a); AddOneSon(T, A); AddOneSon(T, BB); BB= D = BuildOneSon(d); AddOneSon(T, D); return T;

  34. Example B ( ) { case token of d: match(d);break; c: match(c); break; b:{ match(b); B( ); break;} other: error(); } You can do it yourself!

  35. Assignment • G = {VT, VN, S, P} • VT = {- , (, ), id} • VN = {E, ET, V, VT} • S = E • P = { E  -E ET   E  (E) V  id VT E  V ET VT  (E) ET  -E VT   } Write recursive- descent parsing program for G.

  36. Assignment • According to the CFG of LeastL, write down recursive-descent parsing program. (根据LeastL语言的上下文无关文法的定义,写出递归下 降法程序.) - (1) calculate predict sets for each production; - (2) check whether the grammar meets the precondition; - (3) if not, rewrite grammar; - (4) write function for each non-terminal symbol; Building parse tree!

More Related