Научная статья на тему 'О LL(1)-ГРАММАТИКАХ, АЛГОРИТМАХ НА НИХ И МЕТОДАХ ИХ АНАЛИЗА В ПРОГРАММИРОВАНИИ'

О LL(1)-ГРАММАТИКАХ, АЛГОРИТМАХ НА НИХ И МЕТОДАХ ИХ АНАЛИЗА В ПРОГРАММИРОВАНИИ Текст научной статьи по специальности «Компьютерные и информационные науки»

CC BY
1120
77
i Надоели баннеры? Вы всегда можете отключить рекламу.
Ключевые слова
СИНТАКСИЧЕСКИЙ АНАЛИЗ / LL(1)-ГРАММАТИКА / ЛЕВАЯ РЕКУРСИЯ / ПРАВОЕ ВЕТВЛЕНИЕ / МНОЖЕСТВА FIRST И FOLLOW / ТАБЛИЦА ПРОГНОЗОВ / МЕТОД РЕКУРСИВНОГО СПУСКА / МЕТОД ВЫБРОСОВ-ПЕРЕНОСОВ

Аннотация научной статьи по компьютерным и информационным наукам, автор научной работы — Козлов Сергей Валерьевич, Светлаков Алексей Владимирович

В статье рассматриваются теоретические основы синтаксического анализа, а именно определяются LL(1)-грамматики и доказываются ключевые для практики положения, связанные с ними. Авторами на примерах демонстрируется непрактичность доказательства по определению, что контекстно-свободная грамматика является LL(1)-грамматикой. Ввиду этого формулируется и доказывается теорема, которая задает критерий LL(1)-грамматики. Производится построение множеств first и follow, которые определяют необходимые и достаточные условия существования LL(1)-грамматики. На примерах показывается применение сформулированного критерия. Центральное место статьи занимает вопрос поиска грамматик эквивалентных LL(1)-грамматике. Рассматривается ряд утверждений, позволяющих выявить, что анализируемая грамматика не является LL(1)-грамматикой. В частности анализируются два необходимых условия существования LL(1)-грамматики. А именно, теорем, что если грамматика содержит левую рекурсию или правое ветвление, то она не является LL(1)-грамматикой. При этом на примере демонстрируется факт того, что эти условия не являются достаточными. Обсуждаются и сравниваются два метода анализа LL(1)-грамматик, применяемых на практике: метод рекурсивного спуска и метод выбросов-переносов. Для каждого из методов приводится его содержательное описание и реализация на псевдокоде. Все положения статьи сопровождаются необходимыми примерами. Актуальность статьи связана с поиском и изучением алгоритмов синтаксического анализа грамматик естественных и искусственных языков, которые успешно применяются как инструменты для написания систем распознавания образов в области искусственного интеллекта.

i Надоели баннеры? Вы всегда можете отключить рекламу.
iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

ABOUT LL(1)-GRAMMARS, ALGORITHMS ON THEM AND METHODS OF THEIR ANALYSIS IN PROGRAMMING

The article discusses the theoretical foundations of parsing, namely, the definition of LL(1)-grammars and proves the key positions associated with them for practice. The authors demonstrate the impracticality of the proof by definition that context-free grammar is an LL(1)-grammar. In view of this, a theorem is formulated and proved that sets the criterion of LL(1)-grammar. First and follow sets are constructed, which determine the necessary and sufficient conditions for the existence of LL(1)-grammar. Examples show the application of the formulated criterion. The central point of the article is the question of finding grammars equivalent to LL(1)-grammar. A number of statements are considered to reveal that the grammar being analyzed is not an LL(1)-grammar. In particular, two necessary conditions for the existence of LL(1)-grammar are analyzed. Namely, theorems that if a grammar contains a left recursion or a right branching, then it is not an LL(1)-grammar. The example shows that these conditions are not sufficient. Two methods for analyzing LL(1)-grammars used in practice are discussed and compared: the recursive descent method and the emission-transfer method. For each of the methods, its meaningful description and implementation in pseudocode is given. All the provisions of the article are accompanied by the necessary examples. The relevance of the article is associated with the search and study of parsing algorithms for grammars of natural and artificial languages, which are successfully used as tools for writing pattern recognition systems in the field of artificial intelligence.

Текст научной работы на тему «О LL(1)-ГРАММАТИКАХ, АЛГОРИТМАХ НА НИХ И МЕТОДАХ ИХ АНАЛИЗА В ПРОГРАММИРОВАНИИ»

О ЬЬ(1)-грамматиках, алгоритмах на них и методах их анализа в программировании

С. В. Козлов, А. В. Светлаков

Аннотация — В статье рассматриваются теоретические основы синтаксического анализа, а именно определяются ЬЬ(1)-грамматики и доказываются ключевые для практики положения, связанные с ними. Авторами на примерах демонстрируется непрактичность доказательства по определению, что контекстно-свободная грамматика является LL(1)-грамматикой. Ввиду этого формулируется и доказывается теорема, которая задает критерий ЬЬ(1)-грамматики. Производится построение множеств first и follow, которые определяют необходимые и достаточные условия существования LL(1)-грамматики. На примерах показывается применение сформулированного критерия. Центральное место статьи занимает вопрос поиска грамматик эквивалентных LL(1)-грамматике. Рассматривается ряд утверждений, позволяющих выявить, что анализируемая грамматика не является LL(1)-грамматикой. В частности анализируются два необходимых условия существования LL(1)-грамматики. А именно, теорем, что если грамматика содержит левую рекурсию или правое ветвление, то она не является LL(1)-грамматикой. При этом на примере демонстрируется факт того, что эти условия не являются достаточными. Обсуждаются и сравниваются два метода анализа LL(1)-грамматик, применяемых на практике: метод рекурсивного спуска и метод выбросов-переносов. Для каждого из методов приводится его содержательное описание и реализация на псевдокоде. Все положения статьи сопровождаются необходимыми примерами. Актуальность статьи связана с поиском и изучением алгоритмов синтаксического анализа грамматик естественных и искусственных языков, которые успешно применяются как инструменты для написания систем распознавания образов в области искусственного интеллекта.

Ключевые слова — синтаксический анализ, ЬЬ(1)-грамматика, левая рекурсия, правое ветвление, множества first и follow, таблица прогнозов, метод рекурсивного спуска, метод выбросов-переносов.

Статья получена 28 декабря 2021.

Козлов Сергей Валерьевич, Смоленский государственный университет, доцент кафедры прикладной математики и информатики, кандидат педагогических наук, доцент (email: svkozlov1981 @yandex.ru)

Светлаков Алексей Владимирович, Смоленский государственный университет, студент физико-математического факультета (email: seferlian@mail.ru)

I. ВВЕДЕНИЕ

В настоящее время развитие ГГ-технологий и их внедрение в большинство сфер жизнедеятельности человека служит катализатором поиска все новых более эффективных решений задач практики [1, 2, 3]. Так теория формальных грамматик выступает средством моделирования работы многих инструментальных сред. Она определяет математический аппарат для формализации различных языков программирования, функциональные методы которых образуют библиотеки ресурсов для выполнения различных сценариев работы [4, 5]. Так, например, одной из актуальных областей приложения формальных грамматик является написание частотных словарей [6, 7, 8], трансляторов [9, 10, 11] и систем распознавания в алгоритмах искусственного интеллекта [12, 13] . Теория формальных грамматик составляет основу для систем распознавания образов и речи, автоматического перевода текста и генерации программного кода, криптографии и интеллектуального анализа данных [14, 15]. При этом в теории формальных грамматик существует несколько направлений

методологий от контекстно-зависимых и контекстно-свободных, до автоматных грамматик и языков [16, 17, 18].

ЬЬ-анализ является одним из способов синтаксического анализа цепочек контекстно-свободных языков (КС-языков), время работы которого линейно зависит от длины цепочки [19, 20]. Более того, его частный случай - ЬЬ(1)-анализ является наиболее простым и интуитивно понятным [21]. Разумеется, за подобные достоинства приходится платить тем, что LL(1)-анализ применим лишь к достаточно ограниченному классу грамматик. В частности, он практически бесполезен при анализе естественных языков, а грамматики искусственных языков приходится приводить к определенному виду, а иногда менять и сам язык. В этих случаях целесообразно применять иные методологии анализа данных и связей между ними [22, 23]. Несмотря на это, на практике LL(1)-анализа часто бывает достаточно для проведения синтаксического

анализа. Например, язык арифметических выражений может быть описан подходящей грамматикой, как и многие языки исполнителей. Известен не один язык программирования, интерпретатор которых основан на LL-анализе.

Две буквы «L» в названии говорят о том, что, во-первых, цепочка считывается слева направо (Left to right), а во-вторых, имитируется ее левосторонний вывод (Leftmost derivation). Единица говорит о том, что одномоментно считывается один символ. Обратим внимание, что «символ» здесь и далее употребляется в широком смысле - это может быть как буква или знак, так и лексема (токен) языка, а то и цепочка, удовлетворяющая регулярному выражению. КЦ1)-анализ проводится над так называемыми LL(1)-грамматиками. Дадим необходимые определения.

II. ОПРЕДЕЛЕНИЕ LL(1)-rPAMMATO№

Определение 1. Пусть G - КС-грамматика. Рассмотрим два произвольных левосторонних вывода цепочки ш в этой грамматике: S ^ рА@ ^ ра@ ^ руц и S ^ pAfi ^ ра р ^ ру% , где р, уЕТ* - цепочки из терминалов: разобранная часть цепочки ш, А Е N, причем существуют правила А^ а и А ^ а', а также а, а',р, ц, ( Е (Т U N)* . Если из выполнения условий: \у\ = 1 или \у\ = 0, ц = % = г следует равенство а = а', то G - КЦ1)-грамматика.

Говоря простыми словами, LL(1)-грамматика - это такая грамматика, что посмотрев на очередной символ (или на конец) выведенной части цепочки, можно однозначно сказать, какое правило было использовано.

Пример 1. Грамматика задана правилами S ^ SS\aSb\е. Эта грамматика порождает язык с правильно сбалансированными символами а и Ъ , то есть каждый символ «а» закрывается справа символом Ъ, причем никакой символ не может быть закрыт раньше, чем закроются вложенные (символы а и Ъ можно заменить на открывающуюся и закрывающуюся скобки соответственно). Требуется определить, является ли грамматика КЦ1)-грамматикой.

Рассмотрим следующую терминальную цепочку, выводимую из аксиомы: «ab». Она выводима из сентенциальной формы вида a^. Так как \а\ = 1, то должно выполняться а = а', но в данной грамматике S ^ SS ^ aSbS = arj и S ^ aSb = (оба левосторонние выводы), где а = SS и а' = aSb . Следовательно, так как а Ф а ' , данная грамматика - не LL(1)-грамматика. Заметим, что из ац и может выводиться одна и та же цепочка «аЬ», однако в общем случае это требование необязательно. Это иллюстрирует следующий пример.

Пример 2. Грамматика имеет правила S ^ aSa\bSb\e. Эта грамматика порождает язык палиндромов четной длины над алфавитом {а, Ь} . Проверим, является ли она LL(1)-грамматикой. Будем анализировать цепочку аац . Построим возможные левосторонние выводы этой цепочки: S ^ aSa ^ аа = aaq и S ^ aSa ^ aaSaa = . Так как \а\ = 1 (второй символ), то должно выполняться а = а', но получаем а Ф а', так как а = е и а ' = aSa. Неформально говоря, получаем, что при встрече второго символа а мы не знаем, каким правилом воспользоваться: S ^ е или S ^ aSa . Следовательно, это не LL(1)-грамматика.

Пример 3. Докажем, что никакой неоднозначный язык не может быть порожден ЬЬ(1)-грамматикой. Действительно, по определению, неоднозначный язык содержит хотя бы одну цепочку, вывести которую можно как минимум двумя различными способами. Рассмотрим эту цепочку. В таком случае на некотором этапе вывода окажется, что pAß ^ paß ^ ш и pAß ^ ра ß ^ ш , причем а Ф а '. Здесь возможны два случая: 1) в цепочке о> непосредственно справа от подцепочки р может стоять символ у, но тогда \у\ = 1 и а Ф а'; 2) ш = р, то есть непосредственно справа от р ничего не стоит, но в этом случае \у\ = 0, а значит paß ^ pyq = ш и pa'ß ^ ру% = ш, или ц = % = £ . Из этого условия следует а Ф а '. Таким образом, любая грамматика неоднозначного языка не будет LL(1)-грамматикой.

Очевидно, доказывать по определению данный факт достаточно проблематично, а порой и невозможно, потому на практике оно не используется.

III. КРИТЕРИЙ ЬЬ(1)-ГРАММАТИКИ

Введем в рассмотрение следующие множества.

Определение 2. Множеством first(a) назовем множество всех терминалов (а также е), с которых могут начинаться любые выводы из ß, то есть first (а) = {а\а ^ aß} U {е если а ^ е}.

Определение 3. Множеством follow (А) назовем множество всех терминалов и символа $ (конца цепочки), которые могут появляться в сентенциальных формах непосредственно справа от нетерминала А : follow(A) = {а\5 ^ aAcß} U {$ если S ^ аА}.

Сформулируем и докажем теорему о связи ЬЬ(1)-грамматик со множествами first(a) и follow(A).

Теорема 1 (критерий LL(1)-грамматики).

G является ЬЬ(1)-грамматикой, тогда и только тогда, когда выполняются условия:

1) A^ a\p ^ first (а) П first (P) = 0;

2) A^a\p, e 6 first (a) ^ follow(A) П first(P) = 0.

Доказательство. Будем рассматривать сентенциальную форму рсу , где р 6Т* -выведенная подцепочка терминалов, с 6Т -текущий терминал, у 6 (N UT)* - оставшаяся еще невыведенная часть цепочки.

Необходимость. G - ЬЬ(1)-грамматика.

Случай 1: допустим, что для А ^ а\р при а Ф р выполняется first(a) П first(p) Ф 0, то есть существует символ с, который находится на пересечении этих множеств. Рассмотрим два левосторонних вывода цепочки рсу. S ^ pAS ^ paS ^ pea 5 и S ^ pAS ^ рР8 ^ рср'8 (последние выводы возможны, так как с 6 first(a) П first(p) ). Так как \с\ = 1, то по определению КЦ1)-грамматики а = р, но это противоречит тому, что А ^ а и А ^ р различные правила.

Случай 2: допустим, что для А ^ а\р при а Ф р и e 6 first (а) выполняется с 6 follow(A) П first(p) . Рассмотрим два левосторонних вывода какой-либо цепочки рсу, где непосредственно справа от нетерминала А встречается символ с: S ^ pAcS ^ pacS ^ рс8 и S ^ pAcS ^ pfícS ^ рср cS. Так как \с\ = 1, то по определению LL(1)-грамматики а = р , получено противоречие.

Достаточность. Известно, что

выполняются условия (1) и (2). Пусть G - не ЬЬ(1)-грамматика.

Случай 1: нетерминал не обращается в e. Тогда у какой-то цепочки рсу возможны два различных вывода вида S ^ pAS ^ paS ^ pea 'S и S ^ pAS ^ рР8 ^ pcfi'S такие, что а Ф р, но это противоречит условию (1), так как follow(A) П first(p) = {с}.

Случай 2: если А^ e, то у какой-либо цепочки рсу возможны различные выводы вида S ^ pAcS ^ pacS ^ рс8 и S ^ pAcS ^ pPcS ^ рср с8 . Но в этом случае follow (А) П first(p) = {с}, что противоречит условию (2). ■

Следует заметить, что в доказательстве рассматривались только левосторонние выводы. Действительно, любой вывод можно сделать левосторонним (об этом говорит еще одна теорема, не рассматриваемая в статье).

Рассмотрим примеры. По определению грамматика из примера 1 не является LL(1)-грамматикой. Покажем, что грамматика не удовлетворяет доказанному критерию. Действительно, first(aSb) = {а}, так как все выводы этой цепочки будут начинаться с символа а . first (SS) = {а} , так как S ^ aSb ,таким образом, нарушается условие (1): first(aSb) П first(SS) = {а}.

Пример 4. Грамматика имеет правила S ^ xSyS\ySxS\e . Эта грамматика порождает

язык с равным количеством символов х и у, расположенных в произвольном порядке. Проверить по критерию, является ли она LL(1)-грамматикой. Очевидно, что условие (1) критерия выполняется: first(xSyS) = {х} , first(ySxS) = {у} , first(е) = {е} . Так как е Е first(e), проверим условие (2): follow(S) = {х, у, $}. Таким образом, данная грамматика - не ЬЬ(1)-грамматика, так как follow(S) П first(xSyS) = {х}.

Пример 5. Рассмотрим язык Дика. Его грамматика выглядит так:

S ^ a1Sb1S\a2Sb2S\ ... \anSbnS\e . Проверим грамматику, согласно критерию. Условие (1) выполняется, так как first(a1Sb1S) = } , first(a2Sb2S) = {а2}, ..., first(anSbnS) = {an}, first (е) = {e} - все множества попарно не пересекаются. Проверим условие (2): follow (S) = {b1t b2,..., bn,$} - множество не пересекается ни с одним из first(aiSbiS) . Таким образом, указанная грамматика является ЬЬ(1)-грамматикой. Это важный пример, так как язык - это последовательность правильно вложенных скобок n типов, что существенно с точки зрения практики, поскольку вложенные скобки присутствуют в записях математических функций и в языках программирования, как в явном виде, так и в виде зарезервированных слов.

IV. АЛГОРИТМЫ ПРИВЕДЕНИЯ К LL(1)-ГРАММАТИКЕ

Заметим, что множества first и follow отличаются даже для одного языка, если он задан разными правилами грамматики. В частности, грамматика S ^ aSbS\e - частный случай языка Дика - является LL(1)-грамматикой и порождает тот же язык, что и грамматика, указанная в примере 1. В связи с этим возникает вопрос: если грамматика не является КЦ1)-грамматикой, можно ли для нее найти эквивалентную грамматику [24], которая является LL(1)-грамматикой?

Теорема 2. Не существует алгоритма, определяющего для произвольной КС-грамматики, существует ли для нее эквивалентная LL(1)-грамматика.

Эта теорема доказывается в рамках теории алгоритмов.

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

Утверждение 1. Если грамматика содержит левую рекурсию, то она не является LL(1)-грамматикой.

По определению левой рекурсии, такая грамматика содержит правила вида А ^ Аа\р,

где ft[1] ФА (наличие только А ^ Аа возможно, если А бесплодный символ, однако правила с бесплодными символами можно удалить, не меняя порождаемого языка). Но в этом случае first(Aa) П first(fi) Ф0 , что противоречит условию (1) критерия. ■

Приведем алгоритм устранения левой рекурсии.

1) Для фиксированного нетерминала запишем все правила в виде А ^ Аа1\Аа2\^\Аап\р1\р1\^\рп, где ft [1] ФА и а^Ф г.

2) Заменим все правила на следующие: А ^ piB\(32B\...\(3nB\(3i\(32\...\(3n.

3) Добавим новые правила В ^ aiB\a2B\ ... \anB\ai\a2\ ...\ап.

Замечание 1. Покажем факт того, что алгоритм не меняет порождаемого языка. До алгоритма нетерминал А порождал цепочки Pkai1ai2 — ain. После применения алгоритма А порождает цепочку ркВ, а В порождает цепочку ai1ai2... ain , что совпадает с цепочкой до алгоритма.

Замечание 2. Выше описан алгоритм устранения непосредственной левой рекурсии, однако встречается более сложная косвенная рекурсия через промежуточные нетерминалы. Существует алгоритм и для ее устранения.

Заметим, что в примере 1 грамматика является леворекурсивной.

Утверждение 2. Если грамматика содержит правое ветвление, то она не является LL(1)-грамматикой.

Правое ветвление в грамматике означает, что в ней присутствуют правила вида А ^ а.р\ау , где а Ф г , но тогда first (aft) П first(ay) Ф 0. ■

Приведем алгоритм устранения правого ветвления.

1) Зафиксируем нетерминал А и запишем его правила в виде А ^ aft1\ ... \afin\ yj ... \Yk , где а Ф е наибольший общий префикс afii и Yj не содержат этот префикс.

2) Заменим все правила на А ^ aB\Y1\ ...\Гк.

3) Введем дополнительные правила В^р1\...\рп.

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

Замечание 3. Отметим, что утверждения являются необходимыми, но не достаточными, то есть, если грамматика не содержит левую рекурсию и правого ветвления, она еще может оставаться не КЦ1)-грамматикой, что иллюстрируют примеры 2, 4.

Пример 6. Составим упрощенную грамматику арифметических выражений: S ^ п\5В5\(5), В ^ +\ *, где п - лексема в виде числа. Данная грамматика является неоднозначной, а значит, ее невозможно привести к КЦ1)-виду. Однако можно придумать более удачную грамматику: S ^ А + S^, А^ В * А\В, В ^n\(S) . Эта грамматика содержит правое ветвление, от которой можно избавиться вышеприведенным алгоритмом. Получится следующая грамматика: S ^ Л5 ' , 5 ' ^ +5\е, А ^ ВА', А ^* А\е, В ^ п\(5).

Полученная грамматика не содержит ни левой рекурсии, ни правого ветвления. Проверим ее по критерию LL(1)-грамматики.

1) first (AS ) = {п, (};

2) first(+S) = {+} , first (е) = {е} , follow(S') = {), $};

3) first (В A') = {n, (};

4) first(* A) = {*} , first (e) = {e} , follow (A') = {),+,$};

5) first(n ) = {n}, first((S) ) = {(}.

Грамматика удовлетворяет теореме 1.

V. МЕТОДЫ АНАЛИЗА LL(1)-rPAMMATOK

Рассмотрим методы анализа LL(1)-грамматик. КЦ1)-анализ представляет собой нисходящий разбор: построение

синтаксического дерева начинается сверху вниз - с аксиомы грамматики.

Различают два широко распространенных способа анализа: метод рекурсивного спуска и метод выбросов-переносов. Вне зависимости от выбранного метода по нему сначала строится таблица прогнозов рассматриваемой грамматики.

В первой строке таблицы прогнозов перечисляются терминалы грамматики, включая символ конца цепочки $, в первом столбце -нетерминалы. В ячейках пишутся правила грамматики, которые из данного нетерминала «приближают» нас к указанному терминалу. Алгоритм построения таблицы прогнозов следующий:

1) Для каждого правила А ^ а (где а -непустая цепочка) и для каждого терминала а Е first (а) помещаем правило А ^ а в ячейку [A,a];

2) Для каждого правила А ^ а такого, что а Е follow(A) и е Е first(a) помещаем правило А ^ а в ячейку [A,a].

3)

Пример 7. Построим таблицу прогнозов для грамматики из примера 6.

Таблица 1

Таблица прогнозов грамматики арифметических выражений

вызывать друг друга, отсюда и название данного метода.

Пример 8. Псевдокод метода рекурсивного спуска по таблице прогнозов из примера 7 (по аналогии можно делать и для других грамматик):

var cur: char; Scan();

function Scan(){

try{gc(); S(); if(cur!=$){ERROR;} write("успешно"); return;} catch(ERROR) {

write(" ошибка в символе ",cur);

return; }

function gc(){ cur:=nextSymbol();}//считывается следующий символ function S() {

if(cur=n\1 cur='('){ A(); S'();} else {ERROR;} }

function S'(){

if(cur='+'){gc(); S(); } elseif(cur=')'\ \ cur='$') {}

else { ERROR; } }

function A(){

if(cur=n\ \ cur='('){B(); A'();} else {ERROR;} }

function A'(){

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

if(cur='*'){gc(); A();} elseif(cur=')'\ \ cur='$'\ \

cur='+') {} else {ERROR; } }

function B(){ if(cur=n){ gc();}

elseif(cur= "("){gc(); S(); if(cur= ") "){gc();} else { ERROR;} }

else { ERROR;} }

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

+ * n ( ) $

5 5 ^ AS ' 5 ^ '

5 ' 5 ' ^ Е 5 ' ^ Е

А А ^ ВА' А ^ ВА'

А' А'^ Е А' А А' ^ Е А' ^ е

В В ^п В^ (S)

В первую очередь рассмотрим метод рекурсивного спуска для синтаксического разбора ЬЬ(1)-грамматик. Опишем этот метод словесно, а затем на псевдокоде напишем его для примера 7.

С помощью отдельной функции gc() цепочка посимвольно считывается слева направо, начиная с первого символа, который считается текущим: cur. В дальнейшем будем иметь в виду, что cur можем быть как символом в классическом понимании, так и лексемой (ее тоже будем называть символом).

Для каждого нетерминала создается функция, носящая его имя, и задача которой найти подцепочку, которая выводится из этого нетерминала, из которой в дальнейшем будет выводиться текущий терминал cur.

Тело каждой функции пишется непосредственно по таблице прогнозов.

В условии оператора if (elseif) текущий символ cur сравнивается с каждым терминалом из таблицы прогнозов, ячейки которой непусты на пересечении имени текущей функции и проверяемого терминала. Если не найдено ни одного совпадения, то работа метода останавливается с ошибкой.

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

Работа метода начинается с вызова функции Scan(), вызывающей gc() и S(), а также содержащей перехватчик ошибок (для мгновенной остановки программы). После реализации всех правил, эта функция проверяет факт того, что gc() остановилась в конце считываемой цепочки - если еще остались символы, то вызывается ошибка, в противном случае работа метода завершается успешно. Заметим, что функции могут рекурсивно

Рассмотрим работу метода выбросов переносов. Опишем его словесно, а затем реализуем программу на псевдокоде.

Стек анализатора содержит в себе все символы грамматики, а также маркер дна «1». В начале работы он содержит только аксиому S и маркер дна непосредственно под ним.

Анализатор считывает текущий терминал cur входной цепочки и смотрит на символ A на вершине стека, а затем принимает решение в зависимости от ситуации.

1) Если A = 1 и cur = $, то анализатор успешно заканчивает работу.

2) Если A = cur, то анализатор снимает со стека верхний символ, а в цепочке переходит к следующему терминалу (вызывается функция nextSymbol();). Таким образом, происходит выброс символа cur со стека.

3) Если A нетерминал, то анализатор должен просмотреть заранее записанную (например, в массив) таблицу прогнозов, а именно ячейку [A, cur]. Если ячейка пуста, то работа анализатора останавливается с ошибкой. Если ячейка непуста, то анализатор снимает нетерминал со стека и переносит правую часть правила в стек, записывая символы по одному в обратном порядке. Заметим, что если правая часть содержит пустую цепочку, то нетерминал просто снимается со стека. В массив следует записывать только правые части правил.

4) Во всех остальных случаях выводится сообщение об ошибке.

Реализация указанного метода на псевдокоде:

var s: stack; var cur:char; s.push(J); s.push(S); NextSymbol(); function parser(){ while (s.top!= 1){ A:=s.top();

if(A=± && cur=$){write("успешно"); break;J//ÄHaMU3 завершен elseif(A=cur){NextSymbol(); s.pop();} //Выброс elseif(A =нетерминал) {

if(M[A,cur]=X1X2...XJ{//M - массив, построенный на основе таблице прогнозов, X1X2...Xn - правая часть правила A -> X1X2.Xn s.pop();

for i=n downto 1{ s.push(Xi)}//перенос в обратном порядке

} else {write("ошибка в символе",cur); ERROR;} //пустая ячейка

} else {write("ошибка в символе",cur); ERROR;}

//прочие случаи }

}

VI. ЗАКЛЮЧЕНИЕ

В заключение рассмотрим еще один важный аспект. Можно обратить внимание на то, что метод выбросов-переносов реализуется в общем виде, меняя для конкретной грамматики лишь массив, тогда как код метода рекурсивного спуска сильно зависит от грамматики. Однако при семантической интерпретации общий код придется подстраивать под конкретные моменты: необходимо выделять разные случаи в зависимости от того, какой терминал или нетерминал считывается.

Пример 9. Рассмотрим несколько состояний стека при разборе цепочки (n+n)*n грамматики из примера 6.

0) Стек {±,S}

1) Указатель перемещается и считывает символ «(», это соответствует учейке [S,(]. Стек: {±,S',A} - нетерминал снимается, а правая часть переносится в обратном порядке.

2) Стек: {±,S',A',B}

3) {±,S',A',B}

4) {±,S',A',),S,(}

5) Так как символ на вершине стека совпадает со считываемым символом, то происходит выброс открывающей скобки, а указатель перемешается к числу n: {±,S',A',),S}

6) И так далее. В конце в стеке останется только маркер дна, а указатель прочитает конец цепочки. Тогда метод успешно завершится.

Подводя итог, можно отметить, что LL(1)-анализатор самый простой для построения интерпретаторов, но применим к ограниченному числу языков (однако для практики, как правило, этого хватает, если не брать в расчет естественные языки). Он реализуется двумя методами, которые обладают своими недостатками и достоинствами: с явным и неявным использованием стека. Таким образом, рассмотренные в статье аспекты являются необходимыми и достаточными условиями для реализации КЦ1)-анализа этими методами.

БИБЛИОГРАФИЯ

[1] Баженов Р. И., Лопатин Д. К. О применении современных технологий в разработке интеллектуальных систем // Журнал научных публикаций аспирантов и докторантов. - 2014. -№ 3 (93). - С. 263-264.

[2] Козлов С. В. Концептуальные возможности использования цифровых технологий в сфере образования // Цифровой регион: опыт, компетенции, проекты: сборник статей III Международной научно-практической конференции, посвященной 90-летию Брянского государственного инженерно-технологического университета. - Брянск, 2020. - С. 396-402.

[3] Мунерман В. И. Реализация параллельной обработки данных в облачных системах // Современные информационные технологии и ИТ-образование. - 2017. Т. 13. № 2. - С. 57-63.

[4] Козлов С. В., Светлаков А.В. Теория формальных грамматик и ее применение // Системы компьютерной математики и их приложения. - 2021. № 22. - С. 358-364.

[5] Муха В. С. Математические модели многомерных данных // Доклады Белорусского государственного университета информатики и радиоэлектроники. - 2014. - № 2 (80). - С. 143158.

[6] Киселева О.М., Тимофеева Н.М. Построение концептуальной модели учебных словарей по педагогическим дисциплинам // Научно-методический электронный журнал «Концепт».

- 2013. - Т. 3. - С. 3216-3220.

[7] Втюрин М. В. Применение формальных грамматик для сокращения объема текстовой информации // Инновационное развитие: технический и технологический аспекты. Сборник статей международной научно-практической конференции. - 2019. - С. 22-25.

[8] Кагиров И. А., Леонтьева А. Б. Автоматический синтаксический анализ русских текстов на основе грамматики составляющих // Известия высших учебных заведений. Приборостроение.

- 2008. - Т. 51. № 11. - С. 47-51.

[9] Волкова И. А., Вылиток А. А., Руденко Т. В. Формальные грамматики и языки. Элементы теории трансляции: учебное пособие для студентов II курса. - М., 2009 - 115 с.

[10] Компиляторы. Принципы, технологии, инструментарий / А. В. Ахо, М. С. Лам, Р. Сети, Д. Д. Ульман. - М., 2008. - 1184 с.

[11] Вирт Н. Построение компиляторов. - М., 2013. -192 с.

[12] Борисенкова А. В., Козлов С. В. Использование метода каскадов Хаара при распознавании образов на изображениях // Развитие научно-технического творчества детей и молодежи: Сборник материалов III Всероссийской научно-практической конференции с международным участием. - 2019. - С. 28-33.

[13] Фаворская М. Н. К вопросу об использовании формальных грамматик при распознавании объектов в сложных сценах // Решетневские чтения. - 2009. - Т. 2. - С. 540-541.

[14] Янченко Е. В. Использование формальных грамматик в криптографии // Современные

проблемы телекоммуникаций: материалы международной научно-технической

конференции. - Новосибирск, 2021. - С. 155158.

[15] Козлов С. В. Интеллектуальная система поддержки принятия решений «Advanced Tester» // Компьютерная интеграция производства и ИПИ-технологии: сборник материалов X Всероссийской конференции. -Оренбург, 2021. - С. 127-131.

[16] Малявко А.А. Формальные языки и компиляторы: учебное пособие для вузов. - М.: Издательство Юрайт, 2020. - 429 с.

[17] Пентус А. Е., Пентус М. Р. Теория формальных языков: учебное пособие. - М: Изд-во ЦПИ при механико-математическом ф-те МГУ, 2004. — 80 с.

[18] Хопкрофт Дж. Э., Мотвани Р., Ульман Дж. Д.. Введение в теорию автоматов, языков и вычислений. - М., 2008. - 528 с.

[19] Скрипов А. В. Описание контекстных условий формальных языков грамматики с контекстуальными аргументами // Вестник Уральского института экономики, управления и права. - 2013. № 1 (22). - С. 111-116.

[20] Мартыненко Б. К. Регулярные языки и КС-грамматики // Компьютерные инструменты в образовании. - 2012. № 1. - С. 14-20.

[21] Козлов С.В., Светлаков А.В. Применение теории формальных грамматик в информатике. Дистанционные образовательные технологии. Сборник трудов VI Международной научно -практической конференции. - Симферополь, 2021. - С. 255-259.

[22] Кристофидес Н. Теория графов. Алгоритмический подход. - М.: Мир, 1978. -432 с.

[23] Козлов С. В. Цифровое моделирование процессов управления социально-экономическими системами с применением методов функционального анализа // Вызовы цифровой экономики: итоги и новые тренды: сборник статей II Всероссийской научно-практической конференции (г. Брянск, 07 июня 2019 г.) [Электронный ресурс]. - Брянск: Брян. гос. инженерно-технол. ун-т., 2019. - С. 233-239.

[24] Байдарманова Б. Н. Некоторые способы нахождения эквивалентных преобразований в контексте свободных грамматик // Theoretical & Applied Science. - 2013. - № 5 (1). - С. 5-11.

About LL(1)-grammars, algorithms on them and methods of their analysis in

programming

Kozlov S.V., Svetlakov A. V.

Abstract — The article discusses the theoretical foundations of parsing, namely, the definition of LL(1)-grammars and proves the key positions associated with them for practice. The authors demonstrate the impracticality of the proof by definition that context-free grammar is an LL(1)-grammar. In view of this, a theorem is formulated and proved that sets the criterion of LL(1)-grammar. First and follow sets are constructed, which determine the necessary and sufficient conditions for the existence of LL(1)-grammar. Examples show the application of the formulated criterion. The central point of the article is the question of finding grammars equivalent to LL(1)-grammar. A number of statements are considered to reveal that the grammar being analyzed is not an LL(1)-grammar. In particular, two necessary conditions for the existence of LL(1)-grammar are analyzed. Namely, theorems that if a grammar contains a left recursion or a right branching, then it is not an LL(1)-grammar. The example shows that these conditions are not sufficient. Two methods for analyzing LL(1)-grammars used in practice are discussed and compared: the recursive descent method and the emission-transfer method. For each of the methods, its meaningful description and implementation in pseudocode is given. All the provisions of the article are accompanied by the necessary examples. The relevance of the article is associated with the search and study of parsing algorithms for grammars of natural and artificial languages, which are successfully used as tools for writing pattern recognition systems in the field of artificial intelligence.

Keywords — parsing, LL(1)-grammar, left recursion, right branching, first and follow sets, prediction table, recursive descent method, emission-carry method.

References

[1] Bazhenov R. I., Lopatin D. K. O primenenii sovremennyh tehnologij v razrabotke intellektual'nyh sistem // Zhurnal nauchnyh publikacij aspirantov i doktorantov. - 2014. - # 3 (93). - S. 263-264.

[2] Kozlov S. V. Konceptual'nye vozmozhnosti ispol'zovanija cifrovyh tehnologij v sfere obrazovanija // Cifrovoj region: opyt, kompetencii, proekty: sbornik statej III Mezhdunarodnoj nauchno-prakticheskoj konferencii, posvjashhennoj 90-letiju Bijanskogo gosudarstvennogo inzhenerno-tehnologicheskogo universiteta. - Brjansk, 2020. - S. 396-402.

[3] Munerman V. I. Realizacija parallel'noj obrabotki dannyh v oblachnyh sistemah // Sovremennye informacionnye tehnologii i IT-obrazovanie. - 2017. T. 13. # 2. - S. 57-63.

[4] Kozlov S. V., Svetlakov A.V. Teorija formal'nyh grammatik i ee primenenie // Sistemy komp'juternoj matematiki i ih prilozhenija. - 2021. # 22. - S. 358-364.

[5] Muha V. S. Matematicheskie modeli mnogomernyh dannyh // Doklady Belorusskogo gosudarstvennogo universiteta informatiki i radiojelektroniki. - 2014. - # 2 (80). - S. 143-158.

[6] Kiseleva O.M., Timofeeva N.M. Postroenie konceptual'noj modeli uchebnyh slovarej po pedagogicheskim disciplinam // Nauchno-metodicheskij jelektronnyj zhurnal «Koncept». - 2013. - T. 3. - S. 3216-3220.

[7] Vtjurin M. V. Primenenie formal'nyh grammatik dlja sokrashhenija ob"ema tekstovoj informacii // Innovacionnoe razvitie: tehnicheskij i tehnologicheskij aspekty. Sbornik statej mezhdunarodnoj nauchno-prakticheskoj konferencii. - 2019. - S. 22-25.

[8] Kagirov I. A., Leont'eva A. B. Avtomaticheskij sintaksicheskij analiz russkih tekstov na osnove grammatiki sostavljajushhih // Izvestija vysshih uchebnyh zavedenij. Priborostroenie. - 2008. - T. 51. # 11. - S. 47-51.

[9] Volkova I. A., Vylitok A. A., Rudenko T. V. Formal'nye grammatiki i jazyki. Jelementy teorii transljacii: uchebnoe posobie dlja studentov II kursa. - M., 2009 - 115 s.

[10] Kompiljatory. Principy, tehnologii, instrumentarij / A. V. Aho, M. S. Lam, R. Seti, D. D. Ul'man. - M., 2008. - 1184 s.

[11] Virt N. Postroenie kompiljatorov. - M., 2013. - 192 c.

[12] Borisenkova A. V., Kozlov S. V. Ispol'zovanie metoda kaskadov Haara pri raspoznavanii obrazov na izobrazhenijah // Razvitie nauchno-tehnicheskogo tvorchestva detej i molodezhi: Sbornik materialov III Vserossijskoj nauchno-prakticheskoj konferencii s mezhdunarodnym uchastiem. - 2019. - S. 28-33.

[13] Favorskaja M. N. K voprosu ob ispol'zovanii formal'nyh grammatik pri raspoznavanii ob"ektov v slozhnyh scenah // Reshetnevskie chtenija. - 2009. - T. 2. - S. 540-541.

[14] Janchenko E. V. Ispol'zovanie formal'nyh grammatik v kriptografii // Sovremennye problemy telekommunikacij: materialy mezhdunarodnoj nauchno-tehnicheskoj konferencii. - Novosibirsk, 2021. - S. 155158.

[15] Kozlov S. V. Intellektual'naja sistema podderzhki prinjatija reshenij «Advanced Tester» // Komp'juternaja integracija proizvodstva i IPI-tehnologii: sbornik materialov X Vserossijskoj konferencii. -Orenburg, 2021. - S. 127-131.

[16] Maljavko A.A. Formal'nye jazyki i kompiljatory: uchebnoe posobie dlja vuzov. - M.: Izdatel'stvo Jurajt, 2020. - 429 s.

[17] Pentus A. E., Pentus M. R. Teorija formal'nyh jazykov: uchebnoe posobie. - M: Izd-vo CPI pri mehaniko-matematicheskom f-te MGU, 2004. — 80 s.

[18] Hopkroft Dzh. Je., Motvani R., Ul'man Dzh. D.. Vvedenie v teoriju avtomatov, jazykov i vychislenij. -M., 2008. - 528 s.

[19] Skripov A. V. Opisanie kontekstnyh uslovij formal'nyh jazykov grammatiki s kontekstual'nymi argumentami // Vestnik Ural'skogo instituía jekonomiki, upravlenija i prava. - 2013. # 1 (22). - S. 111-116.

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

[20] Martynenko B. K. Reguljarnye jazyki i KS-grammatiki // Komp'juternye instrumenty v obrazovanii. -2012. # 1. - S. 14-20.

[21] Kozlov S.V., Svetlakov A.V. Primenenie teorii formal'nyh grammatik v informatike. Distancio nnye obrazovatel'nye tehnologii. Sbornik trudov VI Mezhdunarodnoj nauchno-prakticheskoj konferencii. -Simferopol', 2021. - S. 255-259.

[22] Kristofides N. Teorija grafov. Algoritmicheskij podhod. - M.: Mir, 1978. - 432 s.

[23] Kozlov S. V. Cifrovoe modelirovanie processov upravlenija social'no-jekonomicheskimi sistemami s primeneniem metodov funkcional'nogo analiza // Vyzovy cifrovoj jekonomiki: itogi i novye trendy: sbornik statej II Vserossijskoj nauchno-prakticheskoj konferencii (g. Bijansk, 07 ijunja 2019 g.) [Jelektronnyj resurs]. -Brjansk: Brjan. gos. inzhenerno-tehnol. un-t., 2019. - S. 233-239.

[24] Bajdarmanova B. N. Nekotorye sposoby nahozhdenija jekvivalentnyh preobrazovanij v kontekste svobodnyh grammatik // Theoretical & Applied Science. - 2013. - # 5 (1). - S. 5-11.

i Надоели баннеры? Вы всегда можете отключить рекламу.