Как определить ассоциацию по правилу без токенов?

У меня есть следующая минимизированная грамматика

Exp : let var '=' Exp in Exp end                     { App (Fn $2 $6) $4 }
    | Exp Exp                                        { App $1 $2 }
    | Exp OpCode Exp                                 { Op $1 Add $3 }
    | '(' Exp ')'                                    { $2 }
    | num                                            { Num $1 }
    | var                                            { Ident $1 }
    | '\\' var '.' Exp                               { Fn $2 $4 }

Exp Exp Правило используется для применения функции в значении. Но если у меня есть что-то вроде myFunc 1 2 по умолчанию это приоритет myFunc (1 2)что не то, что я хочу. я хочу (myFunc 1) 2для карри.

Но как я могу определить ассоциацию, если у меня нет нетерминального символа? Пытаюсь сделать %left Exp кажется, не помогает

1 ответ

Решение

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

Exp: Exp Exp %prec CURRY

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

Поскольку вы не можете сделать это коротким путем, вам нужно вернуться к старомодному стилю, где вы пишете однозначную грамматику с явными правилами приоритета:

Curry: Term
     | Curry Term

(Это лево-ассоциативно, на выезде. Если func 1 2 анализируется как ((func 1) 2), то приложение связывается слева.)

Предполагая, что инфикс связывает более крепко, чем приложение, вы должны иметь:

Term: Value
    | Term Opcode Value

Value: '(' Exp ')'
     | num
     | var

Exp: Curry

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

Другие вопросы по тегам