2011-01-08 11 views
0

Я ищу однозначную грамматику для арифметических выражений без лишних круглых скобок. Например, круглые скобки являются избыточными в id+(id*id), но не в (id+id)*id.Недвусмысленная грамматика для арифметических выражений без избыточной скобки

+0

[Обратная ссылка по-польски] (http://en.wikipedia.org/wiki/Reverse_Polish_Notation) - Нет избыточных круглых скобок :-) –

+0

Я не верю, что есть разумный способ * отклонить * ввод, содержащий " избыточная "скобка с инфиксной записью в CFG. –

+0

Но этот вопрос появляется в некоторых книгах, а также при рассмотрении кандидатуры Пеннского государственного университета! поэтому, должно быть какое-то решение! – Moonwild

ответ

2

Это зависит от того, что вы подразумеваете под «для арифметических выражений без лишних скобок». Это будет принимать выражения без каких-либо избыточных скобок, но также будет принимать произвольно вложенные скобки:

expr ::= factor 
expr ::= factor mul_div factor 

mul_div ::= '*' | '/' 

factor ::= term 
factor ::= term add_sub term 

add_sub ::= '+' | '-' 

term ::= NUMBER 
term ::= '(' expr ')' 

Я предполагаю, что ЧИСЛО удается распознать подписанные номера, так что нет унарных плюс или минус там. Вы можете решить, как обращаться с ними, если они вам понадобятся. Вы также можете добавить переменные и т. Д., Если они вам понадобятся.

Если вы имеете в виду грамматику, которая отвергает выражения, которые имеют ненужные круглые скобки, тогда я думаю, что вы ищете что-то, что не является контекстно-свободной грамматикой.

+0

Дело в том, что, как вы сказали в последнем абзаце, он отвергает выражения, которые имеют ненужные круглые скобки, например, в id + (id * id). – Moonwild

+1

@Mahshid: Я уверен, что это невозможно сделать без контекстной грамматики. Не уверен, но почти наверняка. Вы также можете уточнить вопрос, чтобы все знали точно, что вы после. Вы можете просто переписать последнее предложение: _ Например, круглые скобки являются избыточными в 'id + (id * id)', поэтому грамматика должна отклонить его, но они не являются избыточными в '(id + id) * id', поэтому грамматика должна принять it._ –

+0

Это вопрос из главы 4 этой книги: – Moonwild

3

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

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

Вы хотите разобрать выражение, например:

expr  ::= expr addsub term 
expr  ::= prodterm 
expr  ::= value 

sum  ::= expr addsub term 

addsub ::= '+' | '-' 

term  ::= prodterm 
term  ::= unit 

prodterm ::= term '*' unit 
prodterm ::= term '/' produnit 

unit  ::= '(' sum ')' 
unit  ::= value 

produnit ::= unit 
produnit ::= '(' prodterm ')' 

value  ::= '0-9'* 

Одинокая значение никогда не может иметь круглые скобки вокруг него. Единицы - это подвыражения выражений умножения; produnits позволяют вставлять скобки в ваши выражения разделения. (5) будет (значение), что невозможно, потому что только у единиц и единиц есть круглые скобки, и они требуют, чтобы в круглых скобках находился некоторый арифметический оператор, если они присутствуют. (значение) не может быть выведено из какого-либо выражения, и ((ничего)) невозможно, потому что только производные и единицы выводятся в круглые скобки. Если вы внимательно изучаете, produnit требует, чтобы * или a/возникали, если была выведена скобка или для ее анализа в качестве единицы или значение без круглых скобок. единицам требуется a + или a - или нет скобок.

((5 + 6)) терпит неудачу, потому что (5 + 6) может анализировать только как единицу, что может сделать ее продуницей, но нет способа поставить круглые скобки вокруг одиночного изделия - нет цепи, которая поворачивается блок или изделие в круглые скобки вокруг одиночного продукта.

Я сломаю свой выбор для вас: 5 * (6 * 7) не анализируется - это термин, когда вы единицу, вы думаете, но тогда (6 * 7) не является единицей, потому что единицы должны быть значениями или круглыми скобками вокруг выражений с хотя бы одной суммой. Когда происходит хотя бы одна сумма, скобки не являются тривиальными. С другой стороны, 5/(6 * 7) совсем не совпадает с 5/6 * 7 - первое похоже на 5/6/7, а второе похоже на 5 * 7/6. Однако 5/(6) - это то же самое, что и 5/6 - одиночные значения не могут встречаться в круглых скобках. Аналогично, 5/(6/7) не совпадает с 5/6/7, потому что первый такой же, как 5 * 7/6, а второй такой же, как 5/(6 * 7). Другими словами, круглые скобки вокруг знаменателя никогда не являются посторонними, если внутри есть голый оператор.

(5 + 6) +7 также невозможно, так как левая часть (и правая сторона) суммы - это либо строгие значения, либо суммы без круглых скобок вокруг суммы, либо продукты без круглых скобок вокруг продукта.Невозможно повернуть

Вы можете убедить себя, что они держат и проверяют, что это однозначно. Вы могли бы продемонстрировать себе, что это выполняется, расширяя его, чтобы включить оператор экспоненции, или даже лучше обобщить его на более высокоприоритетные операторы или операторы с более низким приоритетом, например == или <.

Надеюсь, это поможет!