По какой-то причине я не смог создать язык, поддерживающий инфиксные, постфиксные и префиксные функции и так далее? - PullRequest
5 голосов
/ 09 января 2009

Я размышлял над созданием языка, который очень хорошо подходил бы для создания DSL, позволяя определять функции, которые являются инфиксными, постфиксными, префиксными или даже состоят из нескольких слов. Например, вы можете определить оператор умножения инфиксов следующим образом (где умножение (X, Y) уже определено):

a * b => multiply(a,b)

Или постфиксный оператор "квадрат":

a squared => a * a

Или троичный оператор в стиле C или Java, который включает два ключевых слова с переменными переменными:

a ? b : c => if a==true then b else c

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

Есть ли какая-то причина, по которой я не вижу, которая сделала бы это чрезвычайно трудным, невозможным или просто плохой идеей?

Редактировать: Несколько человек указали мне на языки, которые могут делать это или что-то в этом роде, но на самом деле меня интересуют указатели на то, как я могу реализовать свой собственный синтаксический анализатор, или проблемы Я мог бы столкнуться при этом.

Ответы [ 4 ]

15 голосов
/ 09 января 2009

Это не так уж сложно сделать. Вам нужно назначить каждому оператору fixity (инфикс, префикс или постфикс) и приоритет . Сделайте приоритет действительным числом; ты поблагодаришь меня позже. Операторы с более высоким приоритетом связываются более тесно, чем операторы с более низким приоритетом; на равных уровнях приоритета вы можете потребовать устранения неоднозначности с круглыми скобками, но вы, вероятно, предпочтете разрешить некоторым операторам быть ассоциативными , чтобы вы могли написать

x + y + z

без скобок. Когда у вас есть фиксирование, приоритет и ассоциативность для каждого оператора, вы захотите написать синтаксический анализатор приоритета оператора . Этот вид синтаксического анализатора довольно просто написать; он сканирует токены слева направо и использует один вспомогательный стек. В книге драконов есть объяснение, но я никогда не находил его очень ясным, отчасти потому, что книга драконов описывает очень общий случай синтаксического разбора операторов. Но я не думаю, что вам будет трудно.

Еще один случай, о котором вы хотите быть осторожным, это когда у вас есть

prefix (e) postfix

, где prefix и postfix имеют одинаковый приоритет. Этот случай также требует скобок для устранения неоднозначности.

Моя статья Распаковка выражений с префиксными и постфиксными операторами имеет пример парсера сзади, и вы можете загрузить код, но он написан на ML, поэтому его работа может быть не очевидна для любителя. Но все дело в исправлении и т. Д. Объясняется очень подробно.

2 голосов
/ 09 января 2009

Что вы собираетесь делать с порядком операций?

a * b squared
1 голос
/ 09 января 2009

Возможно, вы захотите проверить Scala, которая имеет своего рода уникальный подход к операторам и методам.

0 голосов
/ 09 января 2009

Haskell имеет именно то, что вы ищете.

...