Если у вас нет необычных требований, то и унарный минус, и возведение в степень в одном и том же нетерминале будут работать нормально, потому что возведение в степень является ассоциативным справа: (синтаксис Yacc / bison)
atom: ID
| '(' expr ')'
factor
: atom
| '-' factor
| atom '^' factor
term: factor
| term '*' factor
expr: term
| expr '+' term
| expr '-' term
Действительно, возведение в степеньдля того, чтобы этот синтаксис был значимым, фактически требуется быть ассоциативным по праву.Рассмотрим альтернативу с левоассоциативным оператором.
Допустим, у нас есть два оператора, ⊕ и ≀, причем left остается ассоциативным и связывает более тесно, чем ≀, так что ≀ a ⊕ b
равно ≀(a ⊕ b)
.
Поскольку left остается ассоциативным, мы ожидаем, что a ⊕ b ⊕ c
будет проанализирован как (a ⊕ b) ⊕ c
.Но тогда мы получаем странность.a ⊕ ≀ b ⊕ c
совпадает с (a ⊕ ≀b) ⊕ c)
или a ⊕ ≀(b ⊕ c))
?Оба варианта, кажется, нарушают простые шаблоны.[Примечание 1]
Конечно, однозначная грамматика могла бы быть написана для каждого случая, но какой из них был бы менее удивительным для программиста, который просто шел по таблице приоритетов?Наиболее вероятным результатом было бы требование стиля, что выражения всегда должны быть заключены в круглые скобки, даже если круглые скобки являются избыточными.(Руководства по стилю C полны таких рекомендаций, и многие компиляторы будут упрекать вас за использование правильных, но «не интуитивных» выражений.)
Примечания:
- Если вы используете приоритетдекларации, вы получите
a ⊕ ≀(b ⊕ c))
, что может быть или не быть интуитивным, в зависимости от вашей интуиции.