抽象語法樹簡介

()簡介css

抽象語法樹(abstract syntax codeAST)是源代碼的抽象語法結構的樹狀表示,樹上的每一個節點都表示源代碼中的一種結構,這因此說是抽象的,是由於抽象語法樹並不會表示出真實語法出現的每個細節,好比說,嵌套括號被隱含在樹的結構中,並無以節點的形式呈現。抽象語法樹並不依賴於源語言的語法,也就是說語法分析階段所採用的上下文無文文法,由於在寫文法時,常常會對文法進行等價的轉換(消除左遞歸,回溯,二義性等),這樣會給文法分析引入一些多餘的成分,對後續階段形成不利影響,甚至會使合個階段變得混亂。因些,不少編譯器常常要獨立地構造語法分析樹,爲前端,後端創建一個清晰的接口。html

抽象語法樹在不少領域有普遍的應用,好比瀏覽器,智能編輯器,編譯器。前端

 

()抽象語法樹實例java

 

(1)四則運算表達式後端

表達式: 1+3*(4-1)+2瀏覽器

抽象語法樹爲:編輯器

 

(2)xmlui

代碼2.1spa

 

  1. <letter>
  2.   <address>
  3.     <city>ShiChuang</city>
  4.   </address>
  5.   <people>
  6.     <id>12478</id>
  7.     <name>Nosic</name>
  8.   </people>
  9. </letter>

 

抽象語法樹.net

 

 

 

 

(3)程序1

代碼2.2

 

  1. while b != 0
  2. {
  3.     if a > b
  4.         a = a-b
  5.     else
  6.         b = b-a
  7. }
  8. return a

 

抽象語法樹

 

(4)程序2

代碼2.3

 

  1. sum=0
  2. for i in range(0,100)
  3.     sum=sum+i
  4. end

 

抽象語法樹

 

()爲何須要抽象語法樹

當在源程序語法分析工做時,是在相應程序設計語言的語法規則指導下進行的。語法規則描述了該語言的各類語法成分的組成結構,一般能夠用所謂的先後文無關文法或與之等價的Backus-Naur範式(BNF)將一個程序設計語言的語法規則確切的描述出來。先後文無關文法有分爲這麼幾類:LL(1)LR(0)LR(1), LR(k) ,LALR(1)等。每一種文法都有不一樣的要求,如LL(1)要求文法無二義性和不存在左遞歸。當把一個文法改成LL(1)文法時,須要引入一些隔外的文法符號與產生式。

例如,四則運算表達式的文法爲:

文法1.1

 

  1. E->T|EAT
  2. T->F|TMF
  3. F->(E)|i
  4. A->+|-
  5. M->*|/

 

改成LL(1)後爲:

文法1.2

 

  1. E->TE'
  2. E'->ATE'|e_symbol
  3. T->FT'
  4. T'->MFT'|e_symbol
  5. F->(E)|i
  6. A->+|-
  7. M->*|/

例如,當在開發語言時,可能在開始的時候,選擇LL(1)文法來描述語言的語法規則,編譯器前端生成LL(1)語法樹,編譯器後端對LL(1)語法樹進行處理,生成字節碼或者是彙編代碼。可是隨着工程的開發,在語言中加入了更多的特性,用LL(1)文法描述時,感受限制很大,而且編寫文法時很吃力,因此這個時候決定採用LR(1)文法來描述語言的語法規則,把編譯器前端改生成LR(1)語法樹,但在這個時候,你會發現很糟糕,由於之前編譯器後端是對LL(1)語樹進行處理,不得不一樣時也修改後端的代碼。

抽象語法樹的第一個特色爲:不依賴於具體的文法。不管是LL(1)文法,仍是LR(1),或者仍是其它的方法,都要求在語法分析時候,構造出相同的語法樹,這樣能夠給編譯器後端提供了清晰,統一的接口。即便是前端採用了不一樣的文法,都只須要改變前端代碼,而不用連累到後端。即減小了工做量,也提升的編譯器的可維護性。

抽象語法樹的第二個特色爲:不依賴於語言的細節。在編譯器家族中,大名鼎鼎的gcc算得上是一個老大哥了,它能夠編譯多種語言,例如cc++,javaADAObject C, FORTRAN, PASCALCOBOL等等。在前端gcc對不一樣的語言進行詞法,語法分析和語義分析後,產生抽象語法樹造成中間代碼做爲輸出,供後端處理。要作到這一點,就必須在構造語法樹時,不依賴於語言的細節,例如在不一樣的語言中,相似於ifconditionthen這樣的語句有不一樣的表示方法

c中爲:

 

  1. if(condition)
  2. {
  3.     do_something();
  4. }

 

     在fortran中爲:

 

  1. If condition then
  2.     do_somthing()
  3. end if

 

在構造ifconditionthen語句的抽象語法樹時,只須要用兩個分支節點來表於,一個爲condition,一個爲if_body。以下圖:

在源程序中出現的括號,或者是關鍵字,都會被丟掉。

 

參考:https://www.jianshu.com/p/6a2f4ae4e099

轉自:http://blog.chinaunix.net/uid-26750235-id-3139100.html

相關文章
相關標籤/搜索