如何通过GLR方法强制解决shift \ reduce冲突? 假设我希望解析器解决右移位运算符和模板参数的两个右尖括号之间的冲突。我让词法分析器连续2次传递“>”符号,作为单独的标记,不将它们合并为一个单独的“>>”令牌。然后我把这些规则放到语法中:
operator_name:
"operator" ">"
| "operator" ">" ">"
;
我希望这是一个转变\减少冲突。如果我有“>”的令牌声明左联结,这不会是冲突。所以我必须删除令牌优先级\ associativity声明,但是这会导致许多其他冲突,我不想通过为每个冲突规则指定上下文优先级来手动解决这些冲突。那么,有没有办法在声明令牌时强制shift \ reduce冲突?
答案 0 :(得分:2)
我相信在operator_name的规则上使用context-dependent precedence会有效。
更新标准指定的C ++语法实际上修改了语法以接受>>令牌关闭两个打开的模板声明。我建议按照它来获得标准行为。例如,您必须小心“x>> y”未被解析为“x>> y”,并且您还必须确保“foo< bar< 2>>>>>”无效,而“foo< bar<(2>>> 1)>>”是有效的。
答案 1 :(得分:1)
我在Yacc(类似于Bison)工作,有类似的情况。
标准语法有时称为“语法定向解析”。
这种情况有时被称为“由语义定向解析”。
示例:
...
// shift operator example
if ((x >> 2) == 0)
...
// consecutive template closing tag example
List<String, List<String>> MyList =
...
让我们记住,我们的思维就像一个编译器。人类的头脑可以编译这个,但以前的语法,不能。 Mhhh。让我们看看人类的思想如何编译这段代码。
如您所知,连续“&gt;”之前的“x”和“&gt;”标记表示表达式或左值。头脑认为“在表达之后,两个连续的大于符号应该成为单个移位运算符令牌”。
对于“字符串”标记:“两个连续的大于符号,在类型标识符之后,应该成为两个连续的模板结束标记标记”。
我认为这种情况不能由通常的运算符优先级,shift或reduce,或只是语法处理,而是使用(“hacking”)解析器本身提供的一些函数。
我没有在您的示例语法规则中看到错误。 “操作符”符号可以避免混淆您提到的两种情况。应该关注使用移位运算符的语法以及连续模板结束标记的部分。
operator_expr_example:
lvalue "<<" lvalue |
lvalue ">>" lvalue |
lvalue "&&" lvalue |
;
template_params:
identifier |
template_declaration_example |
array_declaration |
other_type_declaration
;
template_declaration_example:
identifier "<" template_params ">"
;
干杯。