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」ブロックのみが続くようにelseブロックを定義する方法がよくわかりません。

ノードと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 に答える