1. 程式人生 > >Graduation Project——用於表示程式的物件

Graduation Project——用於表示程式的物件

語言處理器在詞法分析階段將程式分割為單詞後,將開始構造抽象語法樹。抽象語法樹AST是一種用於表示程式結構的樹形結構。抽象語法樹的構造過程稱為語法分析,依然屬於語言粗利器的前半段。因為經過詞法分析後,程式已經被分解為一個個單詞,語法分析的主要任務是分析單詞之間的關係。比如判斷哪些單詞屬於同一個表示式或語句,以及處理左右括號(單詞)的配對等問題。語法分析的結果能夠通過抽象語法樹來表示,這個階段還會檢查程式中是否包含有語法錯誤。

抽象語法樹的定義

在這裡插入圖片描述
已經得到token流的我們,再通過語法分析就能得到如圖所示的物件形式表示的樹形結構。
BinaryExpr物件用於表示雙目運算表示式,譬如1+2,1*2等等。NumberLiteral物件是一個整型字面量。Name物件表示變數名。
當然可以簡化為如下的形式:
在這裡插入圖片描述

設計節點類

為了保持簡潔,所有節點類都是ASTree的子類。ASTLeaf類和ASTList類是ASTree的直接子類。ASTLeaf是節點的父類,ASTList是非葉節點的父類。
其他類都是它倆的子類。
在這裡插入圖片描述
下面來看看程式碼:

package stone.ast;

import java.util.Iterator;

public abstract class ASTree implements Iterable<ASTree>{
    public abstract ASTree child(int i);//返回第i個子節點
    public abstract
int numChildren();//返回子節點的個數(葉子節點返回0) public abstract Iterator<ASTree> children();//(子節點iterator) public abstract String location();//返回AST節點在程式內所處位置的字串 public Iterator<ASTree> iterator(){//介面卡,把ASTree類轉為Iterable型別 return children(); } }

其他程式碼略。

BNF

要構造抽象語法樹,語言處理器首先要知道將會接收哪些單詞序列,並確定希望構造出怎樣的抽象語法樹。通常,這些設定由程式設計語言的語法決定。
語法規定了單詞的組合規則,例如,雙目運算表示式應該由哪些單詞構成,或者if語句應該具有怎麼樣的結構等等。而程式設計語言的語法通常會包含諸如if語句的執行方式,或者通過extends繼承類時將執行哪些處理等規則。不過,這裡討論的語法不含那些程式設計語言範疇的內容,僅考慮如何處理詞法分析器傳來的單詞序列。
舉例來講,我們看一下一條僅包含整型字面量與四則運算的表示式。程式碼採用BNF(Backus-Naur Form,巴克斯正規化)的書寫方式。
BNF中用到的元符號:

  • {pat}:模式pat至少重複0次
  • [pat]:與重複出現0次或1次的模式pat匹配
  • pat1|pat2:與pat1或者pat2匹配
  • ():將括號內視為一個完整的模式

通過BNF來表示語法的例子:

  • factor:NUMBER|"(“expresion”)"
  • term:factor{("*"|"/")factor}
  • expression:term{("+"|"-")term}

:左側寫的內容能夠用於表示在:右側寫的模式相匹配的單詞序列。所以左側出現的諸如factor這樣的符號稱為非終結符。而終結符是一些實現規定好的符號,表示各種單詞,即右側的諸如NUMBER,以及雙引號"括起來的諸如"("就是終結符號。另一方面,右側也含有expression這樣的非終結符。

理解:
factor表示NUMBER或者由左右括號括起來的expression的單詞序列。
term是由factor與運算子*或/構成的序列,其中factor至少出現一次,並且運算子必須夾在兩個factor之間(因為{}括起來的模式可以出現0次或多次,因此term的規則很容易理解)。
expression是由term與運算子+、-構成的序列。
我們其實可以猜測出來,上面就是一個運算表示式的表示。

我們繼續13+4*2的例子,它經由詞法分析後的結果是:
NUMBER "+" NUMBER "*" NUMBER
形象的說就是:
在這裡插入圖片描述

語法分析與抽象語法樹

圖的左上方是語法分析的結果,右下方是構造的抽象語法樹,正好上下顛倒:
在這裡插入圖片描述