以下是我正在尝试的内容:
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
节点和if
节点的else
块节点将是最佳的,因为当我尝试时我不必返回并检查先前的兄弟节点遍历AST。
如果您需要查看更多语法...请告诉我。 “块”基本上定义为{ 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;
也不喜欢。仍然会发出警告。
答案 0 :(得分: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;
答案 1 :(得分:1)
我猜这里,但你不应该把IF定义为:
if_condition.Rule = ToTerm("if") + "(" + comparison + ")" + block;
然后继续将else部分定义为:
else_block.Rule = ToTerm("else") + block;
最后把它们放在一起:
if_else.Rule = if_condition + else_block;
再一次,我猜这里,因为我还没有和EBNF合作过。