Разрешение конфликта уменьшения-уменьшения

Проблемная часть грамматики:

expr_var: var_or_ID
| expr_var '[' expr ']'
| NEW expr_var '(' expr_listE ')'
| expr_var '(' expr_listE ')'
| expr_var ARROW expr_var
| expr_var ARROW '{' expr_var '}'
| expr_var DCOLON expr_var 
| expr_var DCOLON '{' expr_var '}'
| '(' expr_var ')'
;

Описание этой проблемы:

expr_var  ->  NEW expr_var '(' expr_listE ')' .   (rule 87)
expr_var  ->  expr_var '(' expr_listE ')' .   (rule 88)

DCOLON  reduce using rule 87 (expr_var)
DCOLON  [reduce using rule 88 (expr_var)]
ARROW   reduce using rule 87 (expr_var)
ARROW   [reduce using rule 88 (expr_var)]
'['     reduce using rule 87 (expr_var)
'['     [reduce using rule 88 (expr_var)]
'('     reduce using rule 87 (expr_var)
'('     [reduce using rule 88 (expr_var)]
$default    reduce using rule 87 (expr_var)

Каждый оператор (СТРЕЛКА, DCOLON...) является левоассоциативным. Оператор NEW неассоциативен.

Как я могу разрешить этот конфликт?


person Artem Prokudin    schedule 21.04.2017    source источник


Ответы (1)


Проблема здесь в двусмысленности:

new foo(1)(2)

Это можно разобрать двумя способами:

(new foo(1))(2) // call the new object
new (foo(1))(2) // function returns class to construct

Какой (если любой) из них семантически выполним, зависит от вашего языка. Вполне возможно, что и то, и другое имеет смысл. Грамматика не дает никаких намеков на семантику.

Таким образом, вам необходимо решить, какой из них (если какой-либо) является предполагаемым синтаксическим анализом, и соответствующим образом разработать грамматику.

Объявления приоритета не помогут, потому что приоритет используется только для разрешения конфликтов сдвига/уменьшения: отношение приоритета всегда существует между продукцией и упреждающим токеном, а не между двумя продукцией.

Bison разрешит конфликты уменьшенного/уменьшенного в пользу первого производства, как это было сделано в этом случае. Таким образом, если синтаксис является допустимым и однозначным, вы можете выбрать, какой синтаксический анализ требуется, изменив порядок производства, если это необходимо. Это оставит вам предупреждение, но вы можете подавить его с помощью объявления %expect-rr.

Вы также можете подавить один или другой синтаксический анализ (или оба), явно изменив грамматику, чтобы исключить выражения new из числа первых аргументов в вызове и/или исключить вызовы из числа первых аргументов new с помощью явного подмножества expr_var.

person rici    schedule 21.04.2017