2

这是我正在尝试的:

foreach_in.Rule = ToTerm("foreach") + "(" + VARIABLE + "in" + list_obj + ")";
foreach_as.Rule = ToTerm("foreach") + "(" + list_obj + "as" + VARIABLE + ")";
for_loop.Rule = ToTerm("for") + "(" + simple_assignment + ";" + comparison + ";" + assignment + ")";
if_condition.Rule = ToTerm("if") + "(" + comparison + ")";
if_else.Rule = if_condition + block + "else"; // <-- PROBLEM
preset_directive.Rule = foreach_in | foreach_as | for_loop | if_else | if_condition;
directive.Rule = preset_directive | custom_directive;
directive_blk.Rule = directive + block;

但我得到一个shift-reduce conflict. 我不太清楚为什么......如果可以的话,它不应该贪婪地抓住“其他”吗?不太确定如何定义 else 块,使其后面只能跟一个“if”块。

我认为带有一个节点和一个节点的if_else块节点是最佳的,因为当我尝试遍历 AST 时,我不必返回并检查前一个兄弟节点。ifelse

如果您需要查看更多语法...请告诉我。“块”基本上定义为{ blah }(之间的一堆语句{})。


尝试将其作为可选块:

custom_directive_kw.Rule = ToTerm("custom_directive1") | "custom_directive2";
custom_directive.Rule = custom_directive_kw + free_args_opt;
foreach_in.Rule = ToTerm("foreach") + "(" + variable + "in" + list_obj + ")" + block;
foreach_as.Rule = ToTerm("foreach") + "(" + list_obj + "as" + variable + ")" + block;
for_loop.Rule = ToTerm("for") + "(" + simple_assignment + ";" + comparison + ";" + assignment + ")" + block;
if_condition.Rule = ToTerm("if") + "(" + comparison + ")" + block + else_blk_opt;
else_blk.Rule = "else" + block;
else_blk_opt.Rule = else_blk | Empty;
preset_directive.Rule = foreach_in | foreach_as | for_loop | if_condition;
directive.Rule = preset_directive | custom_directive;
directive_blk.Rule = directive;

也不喜欢这样。仍然抛出警告。

4

2 回答 2

2

没关系...讽刺有这个神奇PreferShiftHere()的功能可以解决问题。

foreach_in.Rule = ToTerm("foreach") + "(" + variable + "in" + list_obj + ")" + block;
foreach_as.Rule = ToTerm("foreach") + "(" + list_obj + "as" + variable + ")" + block;
for_loop.Rule = ToTerm("for") + "(" + simple_assignment + ";" + comparison + ";" + assignment + ")" + block;
if_condition.Rule = ToTerm("if") + "(" + comparison + ")" + block;
if_else.Rule = if_condition + PreferShiftHere() + "else" + block;
preset_directive.Rule = foreach_in | foreach_as | for_loop | if_else | if_condition;
directive_blk.Rule = preset_directive | custom_directive;
于 2011-03-28T04:08:24.790 回答
1

我在这里猜测,但您不应该将 IF 定义为:

if_condition.Rule = ToTerm("if") + "(" + comparison + ")" + block;

然后继续将 else 部分定义为:

else_block.Rule = ToTerm("else") + block;

最后把它们放在一起:

if_else.Rule = if_condition + else_block;

再一次,我在这里猜测,因为我还没有使用 EBNF。

于 2011-03-28T03:27:36.173 回答