词法&语法

词法的意思是构造词语的方法,例如「游泳」这个词语,首先它是个动词,然后我们用了「游」和「泳」两个字,所以如果我们要构造一个词语,我们首先要考虑有哪些字可以用,因为词语都是字构成的,其次我们再考虑我们构造的词语的词性是什么,是动词、名词、还是形容词或者其他之类的。

语法则是造句的方法,因为一个语句是由词语构成的。

在编译器的制作过程中,我们使用正则表达式来表述词法;然后用状态机来实现正则表达式。

串&语言

  • 字母表(alphabet):一个语言所支持的所有字符(如:ASCII、UTF8)
  • 串(string):语言中字母表的一个有穷序列,比如「apple」就是英语的一个串、「你好」就是中文的一个串。也有「空串」的概念。
  • 不可能所有的串就是语言支持的,比如「好你」在中文中就不是个有效的串,所以我们需要一些规则来约束串,其中就有正则表达式

词法分析器的目标

  • 给定程序语言 L 以及所有 L 支持的词汇,从中找出这些词汇,并为他们标注词性。
  • 如果源代码中有语言不支持的词汇,报错并提示用户。

正则表达式

可用于正则语言,用一串字符串来描述正则语言支持哪些词语,但正则语言本身不需要理解这些词语,比如:/apple|banana/,这个正则表达式表示我接收 apple 和 banana 这两个词语,但是正则表达式本身并不需要理解词语的含义。

正则语言可以被确定、有限状态的自动机理解。

通常我们可以用正则表达式来描述一类词法单元(符号)

  • 关键字:(if|else|return|...)
  • 整数:[+-]?[0-9]+

举例:区分关键词和变量名

  • 关键词变量名都以字母下划线开头,但又有所区别。
  • 正则表示:以下划线,大小写字母开头,由于下划线、大小写字母、数字组成。
[_a-zA-Z][_a-zA-Z0-9]*

那我们的分析过程是这样的:

  1. 状态 0:把首字母「[_a-zA-Z]」通过转换函数,转换成状态 1 。

2. 状态 1:如果只有一位,那它已经是个符号(token)了,如果还有更多位,则继续转换。

3. 状态 2:把剩余的「[_a-zA-Z0-9]」都用转换函数转换,直到碰到其他字符,就停止了,可以输出为符号(token)。

4. 如果这个符号在字典中,那么就是关键字,如果不在,那么就是变量。其中第二步如果只有 1 位,那么也可以直接输出 token,也是走这步逻辑。

实现判断当前字符类型的工具类​github.com实现提取变量或关键字​github.com实现提取字符串方法​github.com
2389f2018b2058f6b97d3625081de958.png
实现提取操作符​github.com
2389f2018b2058f6b97d3625081de958.png
实现提取数字​github.com
2389f2018b2058f6b97d3625081de958.png
整合词法分析器​github.com
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐