Симметрично, как показано ниже.
E -> E + T | E - T | T
T -> T * F | T/F | X
X -> X^Y | Y
Y -> i | (E)
Объяснение:
==========
Заметим, что это грамматика однозначна. Для того, чтобы сгенерировать выражение состоит из операторов ^
, *
, /
, +
, -
, во-первых, мы должны начать писать шаги, в которых низший приоритет операторов, так что +
, -
могут быть добавлены прежде, чем выше один, т.е. *
/
. А затем ^
можно добавить в целевое выражение в конце. Следовательно, в дереве абстрактного синтаксиса (синтаксического дерева) оператор ^
будет отображаться внизу (в сторону листьев). Таким образом, если мы оценим это выражение в соответствии с деревом, то сначала выполним ^
.
Примечание: В соответствии с правилами грамматики, в сентиментальной форме X -> O^Y
мы не можем вернуться назад, чтобы добавить +
, -
.., Но если у вас есть какие-либо сентиментальное форму из E+T | E-T | T
тогда мы можем еще добавить другие операторы снова. Итак, в этой форме грамматики мы контролируем поток генерации любого допустимого выражения (строки), принадлежащего языку грамматики. (Это то, как управлять приоритетом оператора в однозначном).
Например, чтобы произвести выражение i + i^i * i
, мы не можем, как E --> T --> X ---> X^Y
, потому что, как только вы X^Y
вы не можете добавить +
, -
(без скобок (E)
).
Возможный выбор, чтобы сгенерировать выражение i + i^i * i
выглядит следующим образом:
E --> E - T --> E + T - T --> E + X - T --> E + X^Y - T --*--> i+i^i*i
`--*-->` means more than one step
оператор
^
добавляется в последнем шаге
Примечание (так может появиться в нижней части в дереве, как показано ниже на схеме):
дерево будет что-то вроде:
E
/| \
/| \
E - T <-- - evaluates 3rd
/| \ '
/| \ '
E + T i <-- + evaluates 2nd
' |
' |
i X
/| \
/| \
X ^ Y <--^evaluates first
' '
' '
i i
NOTE:
in tree ' means more than one steps
'
^has higher precedence
because of Left to right associativity + evaluated before then -
Когда вы начинаете оценивать это дерево, то ^
будет б e оценивается первым.
Помните, что операторы с высоким приоритетом всегда добавляются снизу, поэтому грамматика должна быть такой, чтобы операторы могли быть добавлены позже (в синтезе предложения).
(вы должны понять, почему в вашей грамматике +
и -
может быть непосредственно генерируются через E
и через T
вы можете добавить *
, /
. Почему другие однозначную версии E -> E*T | E/T | T
, T -> T+F | T-F | X
не правильно! Где, как язык, порожденное этим грамматика и ваша грамматика эквивалентны. Причина в том, что ваша грамматика генерирует правильное дерево из оценочной точки уважения)
Кроме того, если вы пишете парсер с использованием инструмента YACC. Вы можете использовать двусмысленную версию этой грамматики с меньшим количеством производственных правил и задавать приоритеты операторов вне правил грамматики (что даст приблизительное представление о том, какой оператор должен сначала оценить, а следовательно, как построить дерево). И это будет предпочтительным способом, чем эта однозначная форма, потому что меньшее количество правил производства строит меньшее дерево в высоком (следовательно, эффективный компилятор - занимает меньше времени для синтаксического анализа).
F-выпуск на самом деле должен быть F -> F^X | B' – Gunther
Да, вы правы. Я исправил свой ответ. –
Извините, что выкалываете что-то старое, но почему производство 'F' должно быть' F -> F^X | B'? Строка 'i^i^i', созданная этой грамматикой, интерпретируется как' (i^i)^i', которая не является право-ассоциативной. Тем не менее, 'i^i^i' следует разбирать как право-ассоциативный по соглашению. Обмен «F» и «X» вокруг дает нам право-ассоциативность. –