|
@@ -41,8 +41,9 @@
|
|
|
.常量 词类_算符, "5"
|
|
|
.常量 词类_括号, "6"
|
|
|
.常量 词类_注释, "7"
|
|
|
-.常量 词类_空格, "8"
|
|
|
-.常量 词类型枚举数量, "8"
|
|
|
+.常量 词类_逗号, "8"
|
|
|
+.常量 词类_空格, "9"
|
|
|
+.常量 词类型枚举数量, "9"
|
|
|
|
|
|
```
|
|
|
词类_整数部分和词类_小数部分是为了迁就小数匹配, 词法分析的时候是跳过这两个的.
|
|
@@ -124,6 +125,30 @@ a + b -> +(a, b)
|
|
|
|
|
|
终于可以开始写递归下降器了.
|
|
|
|
|
|
+## 递归下降
|
|
|
+我不觉得我谈论递归下降能比网上的其他教程更好, 随便找了两个参考链接.
|
|
|
+
|
|
|
+额外阅读:
|
|
|
+- 递归下降器
|
|
|
+- - https://zhuanlan.zhihu.com/p/31271879
|
|
|
+- - https://zh.wikipedia.org/wiki/%E9%80%92%E5%BD%92%E4%B8%8B%E9%99%8D%E8%A7%A3%E6%9E%90%E5%99%A8
|
|
|
+
|
|
|
+接下来将假设你有基础的相关知识了. 考虑合规的表达式要么是 `f(args)` `x + y`, 要么是二者在括号内外通过算符连接, 因此给出如下定义
|
|
|
+
|
|
|
+```
|
|
|
+# 尖括号内是词类型, 大括号内是语法
|
|
|
+# * 与正则表达式内星号含义相同, 指匹配0或任意次 ((女装)*)
|
|
|
+# + 与正则表达式内星号含义相同, 指匹配至少1次
|
|
|
+# | 表 或.
|
|
|
+
|
|
|
+表达式 := 加后表达式 (("+" | "-") 加后表达式)*
|
|
|
+加后表达式 := 因子 (("*" | "/") 因子)*
|
|
|
+因子 := 左括号 表达式 右括号 | 函数 | 数字
|
|
|
+函数 := 标识符 左括号 (表达式 (逗号 表达式)*){0,1} 右括号
|
|
|
+
|
|
|
+```
|
|
|
+光写出来构造还是蛮简洁的, 匹配表达式时可以沿着`表达式->加后表达式->因子->函数->表达式`走, 这就是递归下降里的递归含义, 而下降则是指自顶向下慢慢解析. 如果你足够敏锐, 一定能意识到这个流程可能出现无限循环, 这就是左递归问题, 好在上面所提到的数学表达式是LL(1)文法(从左往右每次多看1个词就可以确定究竟是什么), 脑子不糊涂一般不会写出来无限循环. 对于更复杂的情况, 可以上LL(k)解析器, 尽量多看几个. 不过还有一些其他处理方法, 后面再提.
|
|
|
+
|
|
|
## 其他
|
|
|
|
|
|
细微之处的东西在代码的注释里.
|
|
@@ -134,9 +159,7 @@ a + b -> +(a, b)
|
|
|
- 正则表达式
|
|
|
- - https://regex101.com/
|
|
|
- - https://www.runoob.com/regexp/regexp-syntax.html
|
|
|
-- 递归下降器
|
|
|
-- - https://zhuanlan.zhihu.com/p/31271879
|
|
|
-- - https://zh.wikipedia.org/wiki/%E9%80%92%E5%BD%92%E4%B8%8B%E9%99%8D%E8%A7%A3%E6%9E%90%E5%99%A8
|
|
|
+
|
|
|
|
|
|
## 下节预告
|
|
|
|