Я не понимаю, как контекстная чувствительность и двусмысленность влияют друг на друга.
Я считаю правильным:
Двусмысленность:
Неоднозначная грамматика приводит к построению более одного дерева синтаксического анализа с использованием либо левого, либо правого вывода. Язык, в котором все возможные грамматики неоднозначны, является неоднозначным языком.
Например, C ++ - неоднозначный язык, потому что x * y всегда может означать две разные вещи, как обсуждается в: Почему нельзя проанализировать C ++ с помощью парсера LR (1)?.
Контекстная чувствительность:
В контекстно-зависимой грамматике есть правила, в которых левая часть этих правил может содержать (не) терминальные символы, дополнительные к одному нетерминальному, требуемому в левой части всех правил различных типов грамматик. Это означает, что вы не можете просто заменить нетерминал при спуске. Вместо этого вы должны сначала взглянуть на окружающие нетерминалы.
Теперь меня беспокоят утверждения, которые более или менее говорят о том, что контекстно-зависимые парсеры могут анализировать неоднозначности, такие как x * y. Например, в вышеупомянутом связанном вопросе утверждается, что «... синтаксический анализатор, который [украшает синтаксическое дерево при его создании] не является контекстно-зависимым, а LR-анализаторы (чистые) контекстно-свободными». На мой взгляд, это означает, что контекстно-зависимые парсеры (в отличие от контекстно-свободных парсеров?) Могут это делать. Другой пример: Является ли какая-либо часть синтаксиса C ++ зависимой от контекста? где на этот вопрос ответят «Да ...». То же самое и здесь: что такое неоднозначная контекстно-свободная грамматика?
Я не понимаю, какое отношение эта неоднозначность C ++ имеет к контекстной чувствительности. Я не думаю, что существует контекстно-зависимая грамматика, способная справиться с этой двусмысленностью. Например, если вы возьмете вымышленное правило типа Typedef, ‹other› *, PointerDeclaration -> Ident "*" Ident
тогда вы все равно не сможете определить (с помощью чистого синтаксического анализа), использовался ли конкретный первый Ident (например, "x") во время Typedef (например, typedef double x;).
Возможно ли, что термин «контекстная чувствительность» используется в связанных вопросах, хотя означает что-то простое, например зависимость от контекста (например, требуется больше информации, чем предоставляется простым синтаксическим анализатором). Или есть какая-то связь между "реальной" контекстной зависимостью "и двусмысленностями.
Изменить. Более конкретный вопрос: есть ли какие-либо двусмысленности в контекстно-свободных грамматиках, с которыми можно справиться с помощью контекстно-зависимых грамматик. Этот вопрос возникает у меня, потому что в связанных вопросах это звучит так, как будто двусмысленность C ++ иногда упоминается как проблема контекстной чувствительности.
Edit2 Дополнительная информация: книга Компьютерные системы утверждает на странице 346, что такие требования, как наличие одинакового количества фактических и формальных параметров, могут быть выражены контекстно-зависимыми грамматиками. Но это очень громоздко, потому что вам понадобится множество сложных правил. Но, возможно, это могло также относиться к неоднозначности C ++, упомянутой ранее. Так что у нас есть такие правила, как
«Typedef double x», ‹other› *, PointerDeclaration -> «x» «*» Идентификатор
Конечно, такие правила будут очень ограниченными, и вам понадобится огромное количество, чтобы выразить каждую возможность. По крайней мере, это может быть подходом к ответу на вопрос, можно ли (теоретически) заменить контекстно-свободные двусмысленности использованием контекстно-зависимых правил.