Написание парсера лямбда-выражений,

data expr = Symbol of string | Lambda of string * expr | App of expr * expr

При написании файла .mly как я могу выразить идею, что последовательность выражений

e1 e2 e3 e4 

Следует разбирать как

App ((App (App e1 e2) e3) e4)

Используя правила:

%public expr_expr:
    | ID        { Symbol ($1) }
    | NUMBER    { Symbol ($1) }
    | LPAREN expr_expr RPAREN { ($2) }
    | LAMBDA ID ARROW expr_expr { Lambda ($2, $4) }
    | expr_expr expr_expr { Apply ($1, $2) }

Дает структуру (e1 , (e2 , (e3 , e4))) в отличие от (((e1, e2), e3), e4). Есть ли способ контролировать ассоциативность правила в отличие от токена?

1
beoliver 18 Дек 2016 в 02:19
Вам следует рассмотреть возможность просмотра довольно хорошо написанного справочного руководства Menhir и содержит ответы на этот и другие вопросы.
 – 
gasche
20 Дек 2016 в 16:26
- Я читал ...
 – 
beoliver
20 Дек 2016 в 18:33

1 ответ

Лучший ответ

Отказ от ответственности: я использую ocamlyacc, а не menhir, поэтому я основываю свой ответ на первом. AFAIUI, последний обратно совместим с ним, поэтому я предполагаю, что мой ответ может быть полезен в любом случае.

Ссылки на документацию http://caml.inria.fr/pub/docs /manual-ocaml/lexyacc.html:

Правила также могут содержать директиву символа% prec в правой части, чтобы переопределить приоритет и ассоциативность правила по умолчанию с приоритетом и ассоциативностью данного символа.

Так что я бы попробовал с

%left Application

Чтобы ваше правило оставалось ассоциативным (в том месте, где вы определяете приоритеты; вам нужно будет определить как минимум относительный приоритет приложения и лямбда-абстракции), а затем измените свое правило на

| expr_expr expr_expr { Apply ($1, $2) } %prec Application

Это делает Application фиктивным символом, используемым только для присвоения ассоциативности и приоритета.

Примечание 1: все вышесказанное - отчасти мои предположения. По-видимому, я сам (успешно) не пробовал. Когда я однажды написал лямбда-грамматику, я усилил ассоциативность, изменив грамматику.

Примечание 2: Если это не работает, как указано выше, вы можете взглянуть на исходный код OCaml. Язык OCaml имеет такой же синтаксис для приложений.

2
kne 18 Дек 2016 в 10:58