2014-12-24 2 views

ответ

2

Вы можете кодировать левую/правую ассоциативность с помощью правил грамматики.

Например, взгляните на этот основной лямбда-исчисления парсер:

https://github.com/ghulette/haskell-parser-examples/blob/master/src/HappyParser.y

Оперативные производства являются:

Expr : let VAR '=' Expr in Expr { App (Abs $2 $6) $4 } 
    | '\\' VAR '->' Expr   { Abs $2 $4 } 
    | Form      { $1 } 

Form : Form '+' Form    { Binop Add $1 $3 } 
    | Juxt      { $1 } 

Juxt : Juxt Atom     { App $1 $2 } 
    | Atom      { $1 } 

Atom : '(' Expr ')'    { $2 } 
    | NUM       { Num $1 } 
    | VAR       { Var $1 } 
3

Принятая ответ не является удовлетворительным.

Правильный способ решения этой проблемы:

%nonassoc VAR LPAREN -- etc... 
%nonassoc APP 

Expr : Expr Expr %prec APP { APPLY $1 $2 } 

То есть:

  • Добавление маркеров призрака очередности под названием APP, и нет необходимости, чтобы сделать его left или right, так как он выиграл «Не важно, так что вы можете сохранить его nonassoc, чтобы не получить неправильную интуицию, что это важно.

  • испачкать Expr правило с %prec APP, как вы делали

  • и самое главное и часто забывают, вы должны дать все маркеры, которые могут появиться в качестве первого знак с Expr производства очередностью ниже, чем у APP, как правило, достигается путем перечисления их где-то выше, либо с left, right или nonassoc для тех, которые не ассоциируют

причина, почему ваш судебный процесс не удалось, вероятно, что вы пропустили последний шаг.

Причина, по которой требуется последний шаг является то, что алгоритм, при решении вопроса перенести на следующий токен или уменьшить APP правило, будут сравнивать старшинства APP правила с приоритетом входящего маркера. И по умолчанию жетоны, о которых вы не упоминаете, имеют высокий приоритет. Поэтому, столкнувшись с:

Expr Expr . LPAREN VAR RPAREN 

, например, было бы сравнить старшинства APP правила (для уменьшения), с приоритетом LPAREN (сместить), и если вы установите его правильно, он будет смещаться , и делать не то.


Остановка вашей грамматики просто уродливая и неприятная.

+0

Это только что помогло мне. Спасибо. – paulotorrens

+1

@paulotorrens, если вы хотите еще более глубокие объяснения, я написал сообщение в блоге об этой проблеме: https://ptival.github.io/2017/05/16/parser-generators-and-function-application/ – Ptival