资讯专栏INFORMATION COLUMN

从零开始写个编译器吧 - tao 语言的文法定义(下)

Michael_Lin / 3254人阅读

摘要:目前为止我们创建的文件列表新上一章中我们提到了个方法它们可以用来描述非终结符和展开式的形式,那么它们又是如何工作的呢文件中定义了一些方法。特别的,注意如下代码这个方法可以纪录被掉的一组非终结符,纪录这些东西有什么用,将在随后的章节介绍。

目前为止我们创建的文件列表:

|- com.taozeyu.taolan.analysis
    |- FirstSetConstructor
    |- LexicalAnalysis
    |- LexicalAnalysisException
    |- NonTerminalSymbol
    |- SignParser
    |- SyntacticDefine[新]
    |- TerminalSymbol
    |- Token

上一章中我们提到了 4 个方法:

node

token

or

sign

它们可以用来描述非终结符和展开式的形式,那么它们又是如何工作的呢?

SyntacticDefine.java 文件中定义了一些 static 方法。


    static NonTerminalSymbol getNonTerminalSymbol(Exp exp) {
        return expContainer.get(exp);
    }
    private static NonTerminalSymbol node(Exp exp) {
        return new NonTerminalSymbol(exp);
    }
    private static NonTerminalSymbol node() {
        return new NonTerminalSymbol(null);
    }
    private static TerminalSymbol token(Type type, String value) {
        return new TerminalSymbol(type, value);
    }
    private static TerminalSymbol token(Type type) {
        return new TerminalSymbol(type, null);
    }

可以看出,这些方法只是稍微封装了一下,具体还要继续追踪 TerminalSymbol.java 和 NotTerminalySymbol.java。

先看看 TerminalSymbol.java 的相关代码:

public final Type type;
public final String value;
final boolean careValue;
TerminalSymbol(Type type, String value) {
    this.type = type;
    this.value = value;
    this.careValue = careValueTypeSet.contains(type);
}

原来只是直接保存成变量罢了。

再看 NotTerminalySymbol.java 的相关代码:

final Exp exp;
Character sign = null;
final ArrayList expansionList = new ArrayList<>();

定义了这些成员变量,其中 expansionList 代表展开式,它由一组 Object[] 组成。

NonTerminalSymbol(Exp exp) {
    this.exp = exp;
}
NonTerminalSymbol or(Object...args) {
    expansionList.add(args);
    return this;
}
NonTerminalSymbol sign(char sign) {
    this.sign = sign;
    return this;
}

NotTerminalySymbol 也是把这些定义的东西保存起来,只不过每个方法返回 this,因此允许我连续调用这些方法。

特别的,注意如下代码:

final ArrayList banList = new ArrayList<>();
NonTerminalSymbol ban(TerminalSymbol...args) {
    for(TerminalSymbol node:args) {
        banList.add(node);
    }
    return this;
}

这个方法可以纪录被 ban 掉的一组非终结符,纪录这些东西有什么用,将在随后的章节介绍。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65541.html

相关文章

  • 从零开始写个译器 - LL(1)

    摘要:希腊字母表示空,这个产生式表明非终结符可以产生一个空。此外,对于一个文法之中的非终结符,还有集集的概念。对于一个非终结符而言,它的集指可能展开的各种形式中,位于第一的所有终结符所组成的集合。 上一章中,我说 Parser 的工作就是依据文法定义,找到一个与源代码匹配的展开方案就可以了。听起来我们只要先给出一个 tao 语言的文法定义,然后写一个找匹配方案的的程序就可以了。 然而事情情况...

    Tony 评论0 收藏0
  • 从零开始写个译器 - tao 语言文法定义(上)

    摘要:一个非终结符可以被展开称为一个串,如上定义便是将这个非终结符展开称为一个又终结符和非终结符混合而成的串。特别注意我定义的方法仅仅用于修饰非终结符,而非展开式,虽然这个例子中我的方法更靠近方法,但并意味着用于修饰展开式。 各位久等了,本系列在新一年的连载中,形式会加入少许变化。首先,我会将 tao 语言编译器(以及运行环境)的全部内容贴在 GitHub 上,在阅读本系列的时候,需要对照 ...

    wuyangchun 评论0 收藏0
  • 从零开始写个译器 - 程序流控制

    摘要:从展开式中,可以看出,除了这个非终结符,还有其他一些非终结符。是可能展开的形式之一,在语言中,如下代码就是一行典型的从表达式来看,它是由一个级表达式和一个类型的非终结符组成。但特别注意结尾的数量词表明,整个非终结符都是可选的。 目前为止我们创建的文件列表: |- com.taozeyu.taolan.analysis |- FirstSetConstructor |- ...

    huangjinnan 评论0 收藏0
  • 从零开始写个译器系列

    摘要:是的,这个系列将呈现一个完整的编译器从无到有的过程。但在写这个编译器的过程中,我可不会偷工减料,该有的一定会写上的。该语言的虚拟机将运行于之上,同时编译器将使用实现。我早有写编译器的想法之前没写过,故希望一边写编译器一边完成这个系列。 是的,这个系列将呈现一个完整的编译器从无到有的过程。当然,为了保证该系列内容的简洁(也为了降低难度),仅仅保证编译器的最低要求,即仅能用。但在写这个编译...

    genedna 评论0 收藏0
  • 从零开始写个译器 - 文法简介

    摘要:而,称之为非终结符。而这个展开方案中对各个非终结符产生式的选择过程,即是对源代码中每一个部分的定性过程。这个过程让能够理解源代码各个部分表示的含义,并以此生成对应的语法树。 我需要定义出 tao 语言的细节,在此,需要引出文法这一概念。所谓文法,即是用于描述语言的一种工具。 例如,一个赋值语句可能写成如下形式: variable = 1 + 3 如何充分定义这个赋值语句的形...

    stormzhang 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<