程序分割爲單詞後,接下來是構造抽象語法樹。java
抽象語法樹(AST,Abstract Syntax Tree)是一種用於表示程序結構的樹形結構。
詞法分析 (分割單詞)-> 語法分析(構造抽象語法樹) express
BinaryExpr對象用於表示雙目運算表達式。app
雙目運算表達式指的是四則運算等一些經過左值和右值計算新值的運算。
抽象語法樹的全部節點都是ASTree的子類ui
ASTLeaf類是葉節點(不含樹枝的節點)的父類 ASTList是含有樹枝的節點對象的父類 其餘類都是ASTList或ASTLeaf類的子類設計
NumberLiteral與Name類用於表示葉節點,BinaryExpr類用於表示含有樹枝的節點,他們分別是上述兩個類的子類code
ASTLeaf child(int i) //返回第i個子節點 int numChildren() //返回子節點的個數(若是沒有子節點則返回0) Iterator<ASTree> children() //返回一個用於遍歷子節點的iterator
BinaryExpr類一樣也有left和right這兩個字段 這兩個字段並不直接在BinaryExpr類中定義,而是經過其父類ASTList類的children字段定義。 如代碼清單4.6所示,BinaryExpr類不含left及right字段,而是提供了left與right方法。這些方法可以分別從children字段保存的ASTree對象中選取,並返回對應的左子節點與右子節點。 BinaryExpr類也沒有圖4.1與圖4.2中出現的用於保存運算符的operator字段。運算符自己是獨立的節點(ASTLeaf對象),做爲BinaryExpr對象的子節點存在。也就是說,BinaryExpr對象含有左值、右值及運算符這三種子節點。 BinaryExpr類沒有operator字段,提供operator方法。該方法將從與運算符對應的ASTLeaf對象中獲取單詞,並返回其中的字符串。orm
package stone.ast; import java.util.Iterator; public abstract class ASTree implements Iterable<ASTree> { public abstract ASTree child(int i); public abstract int numChildren(); public abstract Iterator<ASTree> children(); public abstract String location(); public Iterator<ASTree> iterator() { return children(); } }
package stone.ast; import java.util.Iterator; import java.util.ArrayList; import stone.Token; public class ASTLeaf extends ASTree { private static ArrayList<ASTree> empty = new ArrayList<ASTree>(); protected Token token; public ASTLeaf(Token t) { token = t; } public ASTree child(int i) { throw new IndexOutOfBoundsException(); } public int numChildren() { return 0; } public Iterator<ASTree> children() { return empty.iterator(); } public String toString() { return token.getText(); } public String location() { return "at line " + token.getLineNumber(); } public Token token() { return token; } }
package stone.ast; import java.util.List; import java.util.Iterator; public class ASTList extends ASTree { protected List<ASTree> children; public ASTList(List<ASTree> list) { children = list; } public ASTree child(int i) { return children.get(i); } public int numChildren() { return children.size(); } public Iterator<ASTree> children() { return children.iterator(); } public String toString() { StringBuilder builder = new StringBuilder(); builder.append('('); String sep = ""; for (ASTree t: children) { builder.append(sep); sep = " "; builder.append(t.toString()); } return builder.append(')').toString(); } public String location() { for (ASTree t: children) { String s = t.location(); if (s != null) return s; } return null; } }
package stone.ast; import stone.Token; public class NumberLiteral extends ASTLeaf { public NumberLiteral(Token t) { super(t); } public int value() { return token().getNumber(); } }
package stone.ast; import stone.Token; public class Name extends ASTLeaf { public Name(Token t) { super(t); } public String name() { return token().getText(); } }
package stone.ast; import java.util.List; public class BinaryExpr extends ASTList { public BinaryExpr(List<ASTree> c) { super(c); } public ASTree left() { return child(0); } public String operator() { return ((ASTLeaf)child(1)).token().getText(); } public ASTree right() { return child(2); } }
BNF(Backus-NaurForm, 巴科斯範式) EBNF(Extended BNF, 擴展巴科斯範式)
BNF能用於表達語言學領域中的Noam Chomsky 上下文無關文法(BNF與上下文無關文法等價)對象
BNF中用到的元符號blog
{ pat } 模式pat至少重複0次 [ pat ] 與重複出現0次或1次的模式pat匹配 pat1 | pat2 與pat1或pat2匹配 {} 將括號內視爲一個完整的模式
factor: 因子 term:項 expression:表達式
只看概念有點難理解 書上的例子比較清楚 token
慢慢開始有難度了,先按計劃看完吧。有些地方可能確實還得在理解理解