Я пытаюсь написать небольшой синтаксический анализатор с иронией. К сожалению, я получаю "конфликт сдвига-уменьшения". Грамматика - не моя сильная сторона, и мне нужно сделать только одну маленькую вещь. Вот сокращенная грамматика, из-за которой возникает ошибка:
ExpressionTerm := "asd"
LogicalExpression :=
ExpressionTerm |
LogicalExpression "AND" LogicalExpression |
LogicalExpression "OR" LogicalExpression
Что означает "конфликт сдвига-уменьшения" и как его решить? Я так понимаю, это означает, что моя грамматика неоднозначна, но я не могу исказить свою логику настолько, чтобы понять, как это сделать.
Добавлено: Для пояснения - «asd» - это просто буквальная строка «asd». Поэтому я ожидал, что с помощью этой грамматики будут проанализированы следующие выражения:
asd
asd AND asd
asd AND asd OR asd
asd OR asd AND asd OR asd
Добавлено 2: Забыл сказать, что корень грамматики - LogicalExpression
.
Добавлено 3: Я понял! Неопределенность возникает из-за того, что выражение вроде
asd AND asd OR asd
можно интерпретировать двумя разными способами:
(asd AND asd) OR asd
asd AND (asd OR asd)
Но как я могу это решить? Хорошо, я могу поставить одно из И или ИЛИ, чтобы оно было сильнее другого (я все равно намеревался). Но теперь я вижу, что ошибка появляется, даже если оператор всего один. Другими словами, это также вызывает ту же ошибку:
LogicalExpression := "asd" | LogicalExpression "OR" LogicalExpression
В этом случае я хочу это:
asd OR asd OR asd
быть проанализировано на это:
(asd OR asd) OR asd
Как это сделать недвусмысленно?
Добавлено 4: Понятно!
LogicalExpression1 := LogicalExpression1 "OR" LogicalExpression2 | LogicalExpression2
LogicalExpression2 := LogicalExpression2 "AND" LogicalExpression3 | LogicalExpression3
LogicalExpression3 := "NOT" LogicalExpression4 | LogicalExpression4
LogicalExpression4 := "asd" | "(" LogicalExpression1 ")"
Это анализирует все логические выражения с приоритетом оператора НЕ-> И-> ИЛИ. "asd" можно заменить выражением, предназначенным для ваших условий.