Я сам наткнулся на ваш вопрос в поисках ответа. Хотя я не нашел канонического алгоритма, я обнаружил, что, как вы говорите, одного приоритета операторов недостаточно для минимального заключения в скобки выражений. Я попытался написать симпатичный JavaScript-принтер на Haskell, хотя мне показалось утомительным писать надежный парсер, поэтому я изменил конкретный синтаксис: https://gist.github.com/kputnam/5625856
Помимо приоритета, вы должны учитывать ассоциативность операторов. Бинарные операции, такие как /
и -
, анализируются как левоассоциативные. Однако присваивание =
, возведение в степень ^
и равенство ==
являются правоассоциативными. Это означает, что выражение Div (Div a b) c
может быть записано a / b / c
без скобок, но Exp (Exp a b) c
должно быть заключено в скобки как (a ^ b) ^ c
.
Ваша интуиция верна: для левоассоциативных операторов, если выражение левого операнда связывает менее жестко, чем его родительский элемент, его следует заключить в круглые скобки. Если выражение правого операнда связывает так же жестко или менее жестко, чем его родительский элемент, его следует заключить в круглые скобки. Таким образом, Div (Div a b) (Div c d)
не требует скобок вокруг левого подвыражения, но правое подвыражение требует: a / b / (c / d)
.
Далее, унарные операторы, в частности операторы, которые могут быть как двоичными, так и унарными, например отрицание и вычитание -
, принуждение и сложение +
и т. Д., Возможно, потребуется обрабатывать в индивидуальном порядке. Например, Sub a (Neg b)
должен быть напечатан как a - (-b)
, даже если унарное отрицание связывает сильнее, чем вычитание. Думаю, это зависит от вашего парсера, a - -b
может быть не двусмысленным, а просто некрасивым.
Я не уверен, как должны работать унарные операторы, которые могут быть как префиксными, так и постфиксными. В таких выражениях, как ++ (a ++)
и (++ a) ++
, один из операторов должен связываться более жестко, чем другой, иначе ++ a ++
будет неоднозначным. Но я подозреваю, что даже если круглые скобки в одном из них не нужны, для удобства чтения вы все равно можете добавить круглые скобки.
person
kputnam
schedule
22.05.2013