У меня есть два фрагмента кода Happy, здесь, где используются правила обычного приоритета, и один, который использует контекстно-зависимые правила приоритета (оба из которых описаны here).Приоритет операционного режима, связанный с контекстом
Normal:
%left '+'
%left '*'
%%
Exp :: { Exp }
: Exp '+' Exp { Plus $1 $3 }
| Exp '*' Exp { Times $1 $3 }
| var { Var $1 }
Контекст-зависимый:
%left PLUS
%left TIMES
%%
Exp :: { Exp }
: Exp '+' Exp %prec PLUS { Plus $1 $3 }
| Exp '*' Exp %prec TIMES { Times $1 $3 }
| var { Var $1 }
Учитывая вход:
a * b + c * d
Обычная версия дает:
Plus (Times (Var "a") (Var "b")) (Times (Var "c") (Var "d"))
в то время как контекстно-зависимой версии дает:
Times (Var "a") (Plus (Var "b") (Times (Var "c") (Var "c")))
не должны они оба дают тот же результат? Что я делаю неправильно здесь, что заставляет их генерировать разные деревья разбора?
Простите меня, если это глупый вопрос, так как я никогда раньше не пользовался счастьем. Означает ли это, что '% left '+'; % left '*' '* does * объявляет приоритеты для' '+' 'и' '*' ', но это'% left PLUS; % left TIMES' * * не объявляет приоритеты для 'PLUS' и' TIMES'? –
@ DanielWagner: Что было непонятно, что я написал? '% left '+'; % left '*' 'объявляет приоритеты для' '+' 'и' '*' 'и'% left PLUS; % left TIMES' объявляет приоритеты для 'PLUS' и' TIMES'. Но сравнение приоритетов всегда между производством и терминалом, а «% left PLUS; % left TIMES' does * not * объявляет приоритеты для ''+'' и ''*''. Почему?И если '' + ''и' '*'' не имеют объявленных приоритетов, нет ничего, чтобы сравнить приоритеты 'PLUS' и' TIMES' с. – rici
Спасибо, что очищает его! Я не понял, что он будет пытаться сравнить приоритет «+» с «ПЛЮС» во втором примере и не преуспеть (потому что только «ПЛЮС» имеет объявленный приоритет там). –