自己写一个编译器:第三天:词法分析

本文详细介绍了词法分析的基本概念、流程和规则,通过一个具体的表达式实例,展示了如何进行词法分析,包括如何识别和处理不同类型的符号、元素和结束标志,最终将原始文本转换为易于处理的token流。

// 请移步《从零开发一个JVM语言》系列。 // 由于这篇文章有人收藏就不删除了。。

看下面这个表达式

1 + 2 * 3.4 - variable.field

它表达了什么呢?

人在观察一个表达式的过程中,实际上已经对它进行了词法分析。

没有接受过编程训练的人看到它的第一眼也会认为它的组成大概是这样:

1+2*3.4-variable.field

这也就是词法分析要做的事。

词法(lexical)分析做的事情很简单,仅仅是将给出的一个或几个句子拆分成便于处理的token流。token流是指一串token。

我在进行词法分析时做的事情很少。仅仅是生成了包含token原始字符和所在位置,外加一些额外信息组成的节点串。

为了说明我的词法分析器,首先定义一个概念,层

class C
    a=1
        <<<>>>

每遇到4个缩进,则视为一个新的“层”。 此例中,有3个层次。class C,a=1,<<<>>>(getter/setter)

此外,有一些符号必然开启一个,即使后面的字符没有换行并添加缩进。


我规定了几个简易的规则,使得其处理起来非常简便。

  • 节点分为3种
    • ElementStartNode 该节点开启一条独立的节点链
    • Element 该节点记录了实际信息
    • EndingNode 该节点表示一个表达式/语句的结束(分为STRONGWEAK,STRONG表示此语句必然结束,WEAK表示,若该语句尚未完成,则可以跨越该节点到下一条继续取token)
  • 规定若干的开启符号
  • 规定若干强结束符号
  • 规定若干分隔符号(表示他们之前和之后是不同的节点,而其本身是否记录为节点要看另一个量:不记录符号)
  • 规定若干不记录符号
  • 规定注释符号
  • 规定若干字符串起始字符
  • 规定若干层起始结束对(PAIR)(由一个开始,由另一个结束)
  • 规定若干特殊符号(这类符号需要特殊处理)

而它们所有,都汇总到一个ListSPLIT中 这个List是有顺序的。所有字符按其字符串长度降序排序。

##解析 一行一行读取。 检查其缩进,若=上一行+4,则视为新的,创建一个ElementStartNode,并在其上链接之后解析的内容 若比上一行小,则视为跳出,找到对应层的ElementStartNode,然后在其后面继续添加节点

取出这一行.trim()后的串LINE,进行如下算法

  • SPLIT中字符串 存在于LINE中,且在LINE中位置的下标最小 且 该串的长度最长的串
  • 对其进行分析,分解出token
  • 取该串之后的字符串,进行递归。

中间的分析过程最重要。不过也很简单

取该串在LINE位置下标之前的LINE的子串,若该串不为空,则记录为token

若该串是层开启符号,则记录该串为token后开启一个新ElementStartNode 若该串是强结束符号,则添加一个EndingNode并标记为强结束 若该串是分隔符号,则判断是否是不记录符号,若不是则记录该串为token 若该串是注释符号,则直接清空这一行后面所有的内容 若该串是字符串起始字符,则找到与之相同的符号,且前面没有转义标记的最先找到的字符,将其视为字符串,记录 若该串是PAIR中的起始,则记录该串后开启一个新ElementStartNode 若该串是PAIR中的结束,则找到对应ElementStartNode后在其后追加该串 若该串是特殊符号,则进行特殊处理

对LINE中尚未被解析的部分进行该算法。

##例子

class C(x=1):S
    y
        <-<>->

会被解析成

class
C
(
    x
    =
    1
)
:
S
    y
        <-<
        (STRONG)
        >->

转载于:https://my.oschina.net/wkgcass/blog/614703

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值