野牛:结构不好
Bison: Bad if structure
我已经在bison中做了一个完整的解析器(当然还有flex中的完整词法分析器(,我昨天才注意到我的解析器有问题。在 If 结构中。
以下是我在解析器中的规则: http://pastebin.com/TneESwUx
在这里无法识别单个 IF,如果我将"%prec IFX"替换为"END",通过添加新的标记"END"("end" return END;
在 flex 中(,它可以工作。但我不想有一个新的"结束"关键字,这就是我不使用此解决方案的原因。
请帮助我。
'处理这种规则的正确方法不是优先级,而是重构使用可选的 else-part,以便解析器可以使用令牌前瞻来决定如何解析。 我会设计成这样:
stmt : IF '(' expression ')' stmts else_part
| /* other statement productions here */
else_part : /* optional */
| ELSE stmts
stmts : stmt
| '{' stmt_list '}'
| '{' '}'
stmt_list : stmt
| stmt_list ';' stmt
(这种特殊大小写stmts
而不是允许stmt
包含块的方法在制作方面可能不是最佳的,并且可能会在您的语言中引入奇怪之处,但没有更多细节,很难确定。 bison
可以生成一份报告,向您显示它生成的解析器的工作原理;你可能想研究它。 还要注意意外的转移/减少冲突,尤其是任何减少/减少冲突。
注意 shift/reduce 冲突在这种语法中是完全正常的; LALR(1( 解析器的要点是将这些冲突作为一个特性, 通过单个标记来解决冲突。 它们被专门报告,以便您可以更轻松地检测您不想要的那些,您通过错误分解语法引入的。
你的IfExpression
也需要重构以匹配;诀窍是else_part
应该产生某种条件表达式来$$
,并且在IF
的生产中你测试$6
(对应于else_part
(并调用适当的IfExpression
构造函数。
你的语法模棱两可,所以你必须忍受转移/减少冲突。END
令牌通过确保 IF
语句始终正确闭合(如一对括号(来消除歧义。
括号在这里是一个很好的类比。假设你有这样的语法:
maybe_closed_parens : '(' stuff
| '(' stuff ')'
;
stuff
本身生成一些语法符号,其中之一是 maybe_closed_parens
。
所以如果你有像 ((((((whatever
这样的输入,这是正确的。括号不必关闭。但是,如果您添加)
呢?它正在关闭哪(
?
这很像无法分辨哪个IF
与ELSE
匹配。
如果将END
添加到IF
的语法中(无论是否存在ELSE
(,那么这就像有一个右括号。 IF
和END
就像(
和)
.
当然,您在风格上不希望在您的语言中END
这个词是正确的,因为您已经有了卷曲的支撑块,这基本上是 Pascal's BEGIN
和 END
的替代拼写。您的}
已经是一个END
关键字。
因此,您可以做的是强加一个规则,即IF
只接受复合语句(即完全大括号(:
if_statement : IF condition compound_statement
| IF condition compound_statement ELSE compound_statement
现在不可能有歧义,比如 if x 如果 y w else z,因为大括号必须存在:if x { if y { w } else { z } } or if x { if y { w } } else { z }
.
我似乎记得 Perl 是做出这种选择的语言的一个例子。这不是一个坏主意,因为它不仅消除了你的歧义,更重要的是它消除了程序中的歧义。
我看到您的语法中没有compound_statement
短语结构规则,因为您的语句会生成一个用{
括起来的短语,并直接}
。如果你采用这种方法,你将不得不破解它。
- 如何循环打印顶点结构
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 预处理器:插入结构名称中的前一个行号
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 孤立代码块在结构中引发异常
- 有什么方法可以遍历结构吗
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 无法将结构注册为增强几何体3D点
- 多成员Constexpr结构初始化
- C++将文本文件中的数据读取到结构数组中
- 如何重构类层次结构以避免菱形问题
- 如何在C++中序列化结构数据
- std::vector的包装器,使数组的结构看起来像结构的数组
- 没有为自己的结构调用列表推回方法
- 奇怪的结构&GCC&clang(void*返回类型)
- 在 c++ 中拥有一组结构的正确方法是什么?
- 野牛:结构不好