Как я могу определить блок "еще"? - PullRequest
2 голосов
/ 28 марта 2011

Вот что я пытаюсь:

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;

Некак то тоже.По-прежнему выдает предупреждение.

Ответы [ 2 ]

2 голосов
/ 28 марта 2011

Неважно ... У Иронии есть волшебная функция 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 голос
/ 28 марта 2011

Я предполагаю здесь, но вы не должны определять IF как:

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

А затем определите остальную часть как:

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

И, наконец, соберите все вместе:

if_else.Rule = if_condition + else_block;

Еще раз, я думаю, здесь, потому что я еще не работал с EBNF.

...