编译器设计中的运算符优先级解析算法是什么?
任何语法字符串都可以使用栈实现进行解析,就像在移进规约解析中一样。但是在运算符优先级解析中,移进和规约是基于栈顶符号和待解析输入字符串的当前输入符号之间的优先级关系来进行的。
运算符优先级解析算法如下:
输入 - 来自某个运算符优先级语法的优先级关系和来自该语法的终端符号的输入字符串。
输出 - 没有输出,但它可以在我们解析时构建一个骨架式的语法树,其中所有内部节点都用一个非终端节点标记,并且没有显示单一产生式的使用。或者,可以将移进-规约步骤的序列视为输出。
方法 - 令输入字符串为 a1a2 … … . an。$最初,栈包含 $。
- 无限循环
- 如果栈中只有 $ 并且输入中只有 $ ,则接受并中断,否则
- 开始
- 令 a 为栈上最顶端的终端符号,令 b 为当前输入符号。
- 如果 a <. b 或 a =. b ,则将 b 移入栈 /*移进*/
- 否则如果 a . > b ,则 /*规约*/
- 重复弹出栈
- 直到栈顶终端符号与最近弹出的终端符号的关系为 <.
- 否则调用错误校正例程 结束。
示例1 - 为语法构建优先级关系表。
E → E + E|E − E|E ∗ E|E⁄E|E ↑ E|(E)| − E|id
使用假设
运算符 | 优先级 | 结合性 |
---|---|---|
↑ | 最高 | 右结合 |
* 和 / | 次高 | 左结合 |
+ 和 − | 最低 | 左结合 |
解答
运算符优先级关系
+ | − | * | / | ↑ | id | ( | ) | $ | |
+ | .> | .> | <. | <. | <. | <. | <. | .> | .> |
− | .> | .> | <. | <. | <. | <. | <. | .> | .> |
* | .> | .> | .> | .> | <. | <. | <. | .> | .> |
/ | .> | .> | .> | .> | <. | <. | <. | .> | .> |
↑ | .> | .> | .> | .> | <. | <. | <. | .> | .> |
id | .> | .> | .> | .> | .> | .> | .> | ||
( | <. | <. | <. | <. | <. | <. | <. | = | |
) | .> | .> | .> | .> | .> | .> | .> | ||
$ | <. | <. | <. | <. | <. | <. | <. |
示例2 -找出以下语法中各种运算符和符号之间的所有优先级关系,并使用优先级表显示它们。
E → E + T|T
T → T ∗ F|F
F → (E)|id
解答
+ | * | ( | ) | id | $ | |
+ | .> | .< | <. | .> | <. | .> |
* | .> | .> | <. | .> | <. | .> |
( | <. | <. | <. | =. | <. | |
) | .> | .> | .> | .> | ||
id | .> | .> | .> | .> | ||
$ | <. | <. | <. | <. |
广告