我正在开发一个小型DSL并且遇到问题让Yacc(Bison)干净地解析以下符号:
START (RETURN expression WHERE expression)* RETURN (expression)?
这是我到目前为止所做的,但我一直在改变/减少冲突,我不知道如何修复它们:
start: START conditional_returns returns |
START returns;
conditional_returns: conditional_returns conditional_return | conditional_return;
conditional_return: RETURN expression WHERE expression;
returns: RETURN expression | RETURN;
我可以看到RETURN关键字在另一个子句中重用的事实导致了问题,但我想了解如何使用这么多规则正确地拆分它。任何帮助将不胜感激?
答案 0 :(得分:1)
上述规则本身不会造成任何问题; yacc / bison可以很好地处理它们,没有转移/减少或减少/减少冲突。您可能遇到问题的地方是start
也是合法的expression
。如果是这种情况,则语言不明确 - 如果start
中有start
,则WHERE可能与任何一个相关联。例如,输入
START RETURN START RETURN expr WHERE expr RETURN expr
可以解析为
START RETURN ( START RETURN expr ) WHERE expr RETURN expr
或
START RETURN ( START RETURN expr WHERE expr RETURN expr )
取决于适合您的DSL的内容,您可以更改语法以强制执行一个或另一个含义,或者如果它们没有意义,则禁止使用嵌套的start
表达式。