两周自制脚本语言-第4天 用于表示程序的对象

第4天 用于表示程序的对象

程序分割为单词后,接下来是构造抽象语法树。

4.1 抽象语法树的定义

抽象语法树(AST,Abstract Syntax Tree)是一种用于表示程序结构的树形结构。

词法分析 (分割单词)-> 语法分析(构造抽象语法树)

file

BinaryExpr对象用于表示双目运算表达式。

双目运算表达式指的是四则运算等一些通过左值和右值计算新值的运算。
file

4.2 设计节点类

抽象语法树的节点类

抽象语法树的所有节点都是ASTree的子类

ASTLeaf类是叶节点(不含树枝的节点)的父类
ASTList是含有树枝的节点对象的父类
其他类都是ASTList或ASTLeaf类的子类

NumberLiteral与Name类用于表示叶节点,BinaryExpr类用于表示含有树枝的节点,他们分别是上述两个类的子类

ASTree类的主要方法

ASTLeaf child(int i) //返回第i个子节点
int numChildren() //返回子节点的个数(如果没有子节点则返回0)
Iterator<ASTree> children() //返回一个用于遍历子节点的iterator
file
file

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对象中获取单词,并返回其中的字符串。

代码清单 4.1 ASTree.java
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(); }
}
代码清单 4.2 ASTLeaf.java
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; }
}
代码清单 4.3 ASTList.java
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;
    }
}
代码清单 4.4 NumberLiteral.java
package stone.ast;
import stone.Token;

public class NumberLiteral extends ASTLeaf {
    public NumberLiteral(Token t) { super(t); }
    public int value() { return token().getNumber(); }
}
代码清单 4.5 Name.java
package stone.ast;
import stone.Token;

public class Name extends ASTLeaf {
    public Name(Token t) { super(t); }
    public String name() { return token().getText(); }
}
代码清单 4.6 BinaryExpr.java
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); }
}

4.3 BNF

BNF(Backus-NaurForm, 巴科斯范式)
EBNF(Extended BNF,  扩展巴科斯范式)

BNF能用于表达语言学领域中的Noam Chomsky 上下文无关文法(BNF与上下文无关文法等价)

BNF中用到的元符号

{ pat }            模式pat至少重复0次

[ pat ]            与重复出现0次或1次的模式pat匹配

pat1 | pat2        与pat1或pat2匹配

{}                 将括号内视为一个完整的模式
file
factor: 因子

term:项

expression:表达式
file

只看概念有点难理解 书上的例子比较清楚


file

4.4 语法分析与抽象语法树

file

慢慢开始有难度了,先按计划看完吧。有些地方可能确实还得在理解理解

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,137评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,824评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,465评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,131评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,140评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,895评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,535评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,435评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,952评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,081评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,210评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,896评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,552评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,089评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,198评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,531评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,209评论 2 357

推荐阅读更多精彩内容