C# 我如何定义“一个”呢;否则";块

C# 我如何定义“一个”呢;否则";块,c#,parsing,grammar,ebnf,irony,C#,Parsing,Grammar,Ebnf,Irony,以下是我正在尝试的: 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 + ";" +

以下是我正在尝试的:

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;

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

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

if_condition.Rule = ToTerm("if") + "(" + comparison + ")" + block;
然后继续将else部分定义为:

else_block.Rule = ToTerm("else") + block;
最后把所有这些放在一起:

if_else.Rule = if_condition + else_block;

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

不用担心。。。反讽有一个神奇的
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;

我可以那样试一下。。。你会注意到,在最后一行,我假设每个“指令”都有一个块,所以我把
+块放在那里,但我可以将块分解到每个块中,并省略最后一行。但不确定这是否能解决歧义。不。我还是不喜欢那样。说“lookaheads[else]。选择轮班作为首选操作。”我不太清楚这意味着什么。这是否意味着如果可以,它将消耗else?还是宁愿避免警告。。。我想我必须把“如果”重新定义为“如果后面有其他选择”。编辑:我也不喜欢那样。我被难住了。这是典型的“悬而未决”问题。如果“……”,那么如果…………“如果”是“属于”,那么“哪个”?解析器生成器告诉您它无法决定。经典的解决方案是强制“else”绑定到最近的“if”。对于LALR解析器生成器,这是通过告诉生成器在“else”关键字上“shift”,而不是“reduce”来完成的。你显然找到了答案。@Ira:是的。。一开始我没有看到歧义,但这是一个很好的例子。这是解决几乎每个LALR解析器生成器中“悬空的其他”问题的经典方法。
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;