2015-05-02 4 views
1

Я пытаюсь написать грамматики, которая поддерживает функции вызовов без использования скобок:Контроллинг Параметр прихлебывая

f x, y 

Как в Haskell, я хотел бы вызовы функций минимально хлебать их параметры. То есть, я хочу

g 5 + 3 

означает

(g 5) + 3 

вместо

g (5 + 3) 

К сожалению, я получаю второй разбор с этой грамматикой:

grammar Parameters; 

expr 
    : '(' expr ')' 
    | expr MULTIPLICATIVE_OPERATOR expr 
    | expr ADDITIVE_OPERATOR expr 
    | ID (expr (',' expr)*?)?? 
    | INT 
    ; 

MULTIPLICATIVE_OPERATOR: [*/%]; 
ADDITIVE_OPERATOR: '+'; 

ID: [a..z]+; 
INT: '-'? [0-9]+; 
WHITESPACE: [ \t\n\r]+ -> skip; 

Дерево разбора, которое я получаю, следующее:

Not the parse tree I want

Я думал, что первый в списке подпункт правила будут получать попытку первым. В этом случае expr ADDITIVE_OPERATOR expr появляется перед вспомогательным устройством ID, так почему же нижняя часть ID имеет более высокий приоритет?

ответ

1

В этом случае ANTLR не правильное преобразование правило (для устранения левой рекурсии и обрабатывать старшинство):

expr 
    : expr_1[0] 
    ; 

expr_1[int p] 
    : ('(' expr_1[0] ')' | INT | ID (expr_1[0] (',' expr_1[0])*?)??) 
     ({4 >= $p}? MULTIPLICATIVE_OPERATOR expr_1[5] 
     | {3 >= $p}? ADDITIVE_OPERATOR expr_1[4] 
    )* 
    ; 

приводит к (expr (expr_1 a (expr_1 5 + (expr_1 3))))

правильно будет:

expr 
    : expr_1[0] 
    ; 

expr_1[int p] 
    : ('(' expr_1[0] ')' | INT | ID (expr_1[5] (',' expr_1[5])*?)??) 
    ({4 >= $p}? MULTIPLICATIVE_OPERATOR expr_1[5] 
    | {3 >= $p}? ADDITIVE_OPERATOR expr_1[4] 
)* 
    ; 

, ведущий к (expr (expr_1 a (expr_1 5) + (expr_1 3)))

Я не уверен, что это ошибка в ANTLR4 или компромисс алгоритма преобразования. Возможно, нужно написать вопрос в ANTLR4 jira.

Чтобы решить вашу проблему, вы можете просто поместить правильно преобразованную грамматику в свой код, и она должна работать. Объяснение преобразования правила найдено в «Окончательном справочнике ANTLR4» на страницах 249ff (и, возможно, где-то в Интернете).

+0

Ручное устранение звуков левой рекурсии похоже на путь. Меня смутила пара других проблем, и я думаю, что я хотел бы лучше понять магию, которую ANTLR выполняет от моего имени. – kaerimasu

+0

Есть ли способ генерировать и просматривать преобразованную грамматику? Что еще более важно, как смешиваются метки, такие как '# Additive', если я вручную изменяю свои леворекурсивные правила, как вы описываете? Возможно ли маркировка? – kaerimasu

+0

Опция командной строки -Xlog должна регистрировать преобразованную грамматику (согласно книге). Я не думаю, что этикетирование работает с этими компактными грамматиками. Но если ручное устранение левого рекурсии - это ваш способ, вам должно быть легко переписать эту грамматику так, чтобы метки были применимы. – CoronA

Смежные вопросы