Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Layt_teor_osnovy_form_yazykov.doc
Скачиваний:
2
Добавлен:
01.04.2025
Размер:
1.17 Mб
Скачать

1.4. Синтаксические деревья и неоднозначность.

Синтаксические деревья помогают понять синтаксис предложений. На рис.1.1. показано то, что мы называем синтаксическим деревом. В качестве иллюстрации построим дерево для следующего вывода предложения 22 грамматики G1 (пример 1.2):

(1.3) <число>=><чс>=><чс><цифра>

=><цифра><цифра>=>2<цифра>=>22

Отправляясь от начального символа <число>, нарисуем его куст для того, чтобы указать первый непосредственный вывод (рис.1.3,а). Куст узла - это множество подчиненных ему узлов (символов). Символы куста образуют цепочку, которая заменяет имя куста в первом непосредственном выводе <число>=><чс>.

Чтобы показать второй вывод, из узла, представляющего заменяемый символ, рисуется куст, узлы которого образуют цепочку, заменяющую этот символ (рис.1.3.,б). Поступая таким же образом, мы построим одну за другой три синтаксические диаграммы, показанные на рис.1.4.

Рис.1.3. Синтаксические деревья для двух выводов.

Концевые (висячие) узлы синтаксического дерева - это узлы, не имеющие подчиненного куста. При чтении слева направо концевые узлы образуют цепочку, вывод которой представлен деревом. Таким образом, после третьего непосредственного вывода в (1.3) цепочка концевых узлов - суть <цифра><цифра> (см. рис.1.4.,а).

Концевой куст - это куст, все узлы которого концевые. На рис.1.3.,б один концевой куст; его узлы <чс> и <цифра>. На рис.1.4.,в два концевых куста с узлами 2 и 2.

Рис.1.4. Синтаксические деревья для вывода.

Когда речь идет о деревьях, часто используется следующая терминология. Пусть N - узел дерева. Сыновьями N называются узлы куста, подчиненного N. N - их отец. Сыновья называются братьями, самым младшим считается самый левый из них. На рис.1.4,б <чс> приходится единственным сыном узла <число>. Тот же самый <чс> имеет двух сынов: <чс> и <цифра>. Отцом узла 2 является <цифра>.

Поддерево синтаксического дерева состоит из узла дерева (называемого корнем поддерева) вместе с той частью дерева (если она имеется), которая исходит из него. Поддеревья тесно связаны с фазами; концевые узлы образуют фазу для корня, данного поддерева. Проследим это более подробно. Если U - корень поддерева и если u - цепочка из концевых узлов поддерева, то U=>+u. Пусть х - цепочка концевых узлов слева от u, а у - цепочка концевых узлов справа от u, т.е., хuу - сентенциальная форма, заданная деревом. Тогда Z=>*хUу, а это означает, что u есть фраза для U в хuу.

Построение вывода по дереву.

Можно восстановить вывод по синтаксическому дереву при помощи обратного процесса. Из рис.1.4,с видно, что концевые узлы образуют цепочку 22. Самый правый концевой куст указывает непосредственный вывод:

2<цифра>=>22

Чтобы пройти по синтаксическому дереву до 2<цифра>, мы отсекаем куст тот дерева - удаляем его. Например, отсекание этого куста (на рис.1.4,в) дает нам дерево на рис.1.4,б. Этот процесс часто называют непосредственной редукцией.

Рассматривая рис.1.4,б, мы видим, что последним здесь должен быть вывод <цифра> <цифра> => 2<цифра>. Это нам дает

<цифра><цифра>=>2<цифра>=>22

Продолжаем процесс, всегда восстанавливая последний непосредственный вывод, на который указывает концевой куст синтаксического дерева, и затем отсекая этот куст.

Подводя итог, сформулируем следующие положения о синтаксических деревьях:

  • для каждого синтаксического дерева существует, по крайней мере, один вывод;

  • для каждого вывода есть соответствующее синтаксическое дерево (но несколько разных выводов могут иметь одно и то же дерево);

  • куст дерева указывает на непосредственный вывод, в котором имя куста заменяется узлами куста. Следовательно, в грамматике существует правило, левой частью которого является имя куста, а правой частью - цепочка из узлов куста;

  • концевые узлы дерева образуют выводимую сентенциальную форму;

  • пусть U-корень поддерева для сентенциальной формы w=хuу, где u образует цепочку концевых узлов этого поддерева. Тогда u - фраза сентенциальной формы w для U. Она является простой фразой, если поддерево представлено единственным кустом.

Кроме вывода (1.3), есть другой вывод предложения 22 в G1.

(1.4) <число>=><чс>=><чс><цифра>

=><цифра><цифра>=><цифра>2=>22

у него то же самое синтаксическое дерево, что и у вывода 1.3. В действительности есть еще и третий вывод 22:

(1.5) <число>=><чс>=><чс><цифра>

=><чс>2=><цифра>2=>22

Заметьте, что эти выводы отличаются лишь порядком применения правил и что синтаксическое дерево не определяет точный порядок, в соответствии с которым осуществляется вывод. На данном этапе это различие порядка в выводах для нас несущественно, и мы считаем, что выводы эквивалентны, если им соответствует одно и то же дерево.

Неоднозначность.

Гораздо более важным является вопрос не единственности синтаксического дерева. Рассмотрим грамматику, содержащую среди прочих правила:

По этим правилам мы могли бы образовать предложение "time flies" двумя различными способами с различными синтаксическими деревьями (рис.1.5).

Рис.1.5. Синтаксические деревья для неоднозначного предложения.

В английском языке каждое из этих предложений имеет смысл

  1. “Время летит ” time в данном случае существительное, а flies глагол в 3-ем лице.

  2. “Хронометрировать мух” time в данном случае глагол, а flies существительное во множественном числе.

Дело в том, что без контекста мы не можем понять предложение, поскольку не можем его правильно разобрать; мы не можем однозначно разделить его на составные части. Поэтому, если компилятор должен уметь транслировать все правильные исходные программы, резонно потребовать, чтобы язык был однозначно определен. Теперь введем следующее

О п р е д е л е н и е 1.10. Предложение грамматики неоднозначно, если для его вывода существуют два синтаксических дерева. Грамматика неоднозначна, если она допускает неоднозначные предложения, в противном случае она однозначна.

Заметим, что мы называем неоднозначной грамматику, а не сам язык. Изменяя неоднозначную грамматику, но, конечно, не изменяя ее предложения, можно иногда получить однозначную грамматику для того же самого множества предложений. Однако есть языки, для которых не существует однозначной грамматики. Такие языки называются существенно неоднозначными.

Не надо забывать, что в данный момент речь идет лишь о синтаксисе. Согласно определению выше, предложение может быть однозначным, но мы можем все же не понять, что оно означает из-за неоднозначного смысла слов.

К сожалению, было доказано, что проблема распознавания неоднозначности алгоритмически неразрешима. Это означает, что не существует алгоритма (т.е. нельзя составить такой алгоритм), который воспримет любую НФБ-грамматику и заведомо определит за конечное число шагов, является она однозначной или нет. Можно, однако, разработать достаточно простые, но нетривиальные условия, такие, что если грамматика им удовлетворяет, то можно утверждать, что она однозначна. Эти условия являются достаточными, но не необходимыми.

Однозначная грамматика для арифметических выражений.

Если сентенциальная форма неоднозначна, то она имеет более чем одно синтаксическое дерево и поэтому в общем случае более чем одну основу. Покажем это на примере, который в то же время предоставит нам очень полезную грамматику для арифметических выражений. Рассмотрим следующую грамматику арифметических выражений, в которой используются единственный операнд(в качестве идентификатора), круглые скобки и бинарные операторы + и *:

(1.6) <Е>::=<Е>+<Е>|<Е>*<Е>|(<Е>)| i.

Сентенциальная форма <Е>+<Е>*<Е> имеет два синтаксических дерева (рис.1.6) и две основы <Е> + <Е> и <Е> * <Е>. Если мы хотим разобрать эту сентенциальную форму, то с какой основы мы должны начать? Грамматика неоднозначна, и можно выбрать любую из основ. Таким образом, мы не можем сказать, что выполняется раньше : сложение или умножение.

Рис.1.6. Два синтаксических дерева для <Е>+<Е>*<Е>.

Рассмотрим теперь грамматику G3[<врж>]:

<врж> ::=<терм>|<врж>+<терм>|<врж>-<терм>

<терм> ::=<множ>|<терм>*<множ>|<терм>/<множ>

<множ> ::=(<врж>)|i

Единственное дерево для выражения i+i*i показано ниже, и, таким образом, в соответствии с этой грамматикой предложение однозначно. В действительности все предложения G3 однозначны. Теперь определим, согласно G3, что в выражении i+i*i должно выполняться раньше: умножение или сложение. Операндами для +, согласно дереву, являются <врж>, из которого получается i, и <терм>, из которого в свою очередь получается i*i. Это означает, что умножение должно быть выполнено первым для того, чтобы образовать <терм> для сложения; следовательно, умножение предшествует сложению.

Рис.1.7.

Грамматику G3 следует предпочесть грамматике 1.6 по двум причинам: она однозначна и указывает, что умножение предшествует сложению.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]