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

StackOverflow https://stackoverflow.com/questions/427040

Вопрос

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

a * b => multiply(a,b)

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

a squared => a * a

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

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

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

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

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

Это было полезно?

Решение

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

x + y + z

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

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

prefix (e) postfix

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

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

Другие советы

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

a * b squared

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top