【编译原理】手工打造语法分析器
创作时间:
作者:
@小白创作中心
【编译原理】手工打造语法分析器
引用
CSDN
1.
https://blog.csdn.net/shuofxz/article/details/137476161
本文将详细介绍编译原理中语法分析器的构建方法,重点讲解递归下降算法和上下文无关文法,并通过具体的代码示例和AST树的生成过程,详细阐述如何处理左递归问题。
一、递归下降算法
还是这个例子:
int age = 45
我们给出这个语法的规则:
intDeclaration : Int Identifier ('=' additiveExpression)?;
如果翻译为程序的话,伪代码如下:
MatchIntDeclare(){
MatchToken(Int); // 匹配 Int 关键字
MatchIdentifier(); // 匹配标识符
MatchToken(equal); // 匹配等号
MatchExpression(); // 匹配表达式
}
输出的 AST 类似于:
Programm Calculator
IntDeclaration age
AssignmentExp =
IntLiteral 45
上面的过程,称为「递归下降算法」。从顶部开始不断向下生成节点,其中还会有递归调用的部分。
二、上下文无关文法
上面的例子比较简单,还可以用正则表达式文法来表示。但如果是个算数表达式呢?正则文法就很难表示了。
- 2+3*5
- 2*3+5
- 2*3
这时我们可以用递归的规则来表示:
additiveExpression
: multiplicativeExpression
| additiveExpression Plus multiplicativeExpression
;
multiplicativeExpression
: IntLiteral
| multiplicativeExpression Star IntLiteral
;
生成的 AST 为:
如果要计算表达式的值,只需要对根节点求值就可以了。这个就叫做「上下文无关文法」。
但你把上述规则翻译为代码逻辑时,会发现一个问题,无限递归。
我们先用个最简单的示例:
additiveExpression
: IntLiteral
| additiveExpression Plus IntLiteral
;
比如输入:
2+3
- 先判断其是不是
IntLiteral,发现不是 - 然后匹配
additiveExpression Plus IntLiteral,此时还没有消耗任何的 token - 先进入的是
additiveExpression,此时要处理的表达式还是2+3 - 又回到开始,无限循环
这里要注意的一个问题:
并不是觉得 2+3 符合 additiveExpression Plus IntLiteral 就能直接按照 + 拆分为两部分,然后两部分分别去匹配。这里是顺序匹配的,直到匹配到该语法规则的结束符为止。在 additiveExpression Plus IntLiteral 中 additiveExpression 的部分,也是在处理完整的 token 的(2+3)。
三、左递归解决方案
改为右递归
如何处理这个左递归问题呢?我们可以把表达式换个位置:
additiveExpression
: IntLiteral
| IntLiteral Plus additiveExpression
;
先匹配 IntLiteral 这样就能消耗掉一个 token,就不会无限循环了。
比如还是 2+3
2+3不是IntLiteral,跳到下面2+3的第一个字符是2被IntLiteral消耗掉,并结束IntLiteral匹配- 然后
+被Plus消耗掉 - 最后
3进入additiveExpression,匹配为第一条规则IntLiteral
这样就结束了,没有无限循环。
改写成算法是:
热门推荐
大孔径霍尔传感器测量误差分析及优化方案
波比跳和跑步哪个减脂?两种运动效果大对比
仓颉输入法如何高效学习:一步步掌握输入技巧和背后原理
战争对股市有何影响?
光纤位移传感器测震:地震监测技术的新突破
MACD线的使用技巧有哪些?这些技巧在实际操作中有哪些局限性?
贵州婚姻家庭调解律师的作用及职责解析
鸡爪的营养价值及功效与作用有哪些
大便溏泄是什么原因
AI与特殊教育的相遇,点亮孩子的学习之路
高铁什么不能带的东西(高铁特殊物品携带规则)
还原湘江“面貌”,看见立体的文明
听说这样汇报工作,一开口就秒杀90%的人
极光追逐攻略:最佳观测时间、地点和设备全解析
中医如何改善湿气重的问题
黑巧克力脂肪碳水含量这么高,为啥减肥推荐吃?
社恐者福音:轻松应对社交场合的策略
普通人的健康减肥方法:一月瘦 10 斤,可长期坚持
上眼眶疼 眼球胀 头疼挂什么科看病
涨知识| 古代年龄称谓大全,0岁——140岁
few 和 a few 用法详解!
口红保质期几年
汽车电子专有名词与相应技术
一文读懂:不同饮食模式和营养素如何影响肠道菌群
探秘北宋铜钱“四大金刚”:宋钱玩家的入门密码
振动FFT频谱分析:原理与应用
如何运用决策矩阵提升决策效率与准确性
总决赛乔丹,总决赛科比,总决赛詹姆斯,没有对比就没有尴尬!
辨别腰痛原因:如何判断您的腰痛是否与肾病有关
水货手机和行货的区别是什么?购买需注意哪些事项