От LR к Glr: обзор синтаксических анализаторов

От LR к GLR: обзор синтаксических анализаторов

Погорелов Д.А., Таразанов А.М., Волкова Л.Л., МГТУ им. Н.Э. Баумана ruine@bk.ru, a-tarazanov@mail.ru, liliya@bmstu.ru

Аннотация

В данной статье рассматриваются преимущества и недостатки алгоритмов синтаксических анализаторов. Дан обзор некоторых существующих методов восходящей рекурсии семейства LR. Результатом этой статьи является сравнительная таблица, которая показывает применимость каждого из рассмотренных анализаторов для определенных типов грамматик и языков. Рассмотрен вопрос практического применения GLR-анализаторов.

Введение

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

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

Проблемами, связанными с обработкой информации, представленной на формальных и естественных языках, занимается компьютерная лингвистика. Благодаря исследованиям в данной области были созданы специальные алгоритмы, которые используются и совершенствуются, позволяя представить текстовую информацию в машиночитаемом виде, пригодном для извлечения фактов компьютером.

Значительная часть задач компьютерной лингвистики основывается на

автоматическом анализе текстов,

представленных на естественном языке. Эта прикладная наука появилась в 60-е годы XX века в ответ на необходимость обработки языка, привычного человеку, при помощи ЭВМ.

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

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

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

1 Синтаксические анализаторы

Синтаксический анализатор — это программа или подпрограмма, производящая сопоставление линейной последовательности лексем формального (языка

программирования, регулярных выражений и т.д.) или естественного языка его формальной грамматике [Борисова, Канищева, 2012]. Согласно [Терехов и др., 2001], по практически любой грамматике возможно построить синтаксический анализатор.

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

Предложена?

Простое предложение

Конструкция с Глагольная

существительным конструкция

Существительное

Man

dog

Рис. 1. Пример синтаксического дерева

На сегодняшний день существует ряд алгоритмов разбора предложений. Все алгоритмы делятся на две группы:

• нисходящие парсеры, которые раскрывают входящую

последовательность, начиная со стартового символа;

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

К первой группе можно отнести LL-парсеры и парсеры рекурсивного спуска. Вторая группа алгоритмов включает парсеры восходящей рекусии, GLR-парсеры и семейство LR-парсеров, рассматриваемое в данной статье.

Взаимосвязь между грамматиками LL- и LR-парсеров можно отобразить схематически так, как представлено на рис. 2.

Рис. 2. Взаимосвязь между грамматиками LL- и LR-парсеров

1.1 LR-анализаторы

Буква L в названии алгоритмов означает, что входная цепочка читается слева направо. Буква R указывает, что анализатором проводится построение правого выхода входной цепочки. Число в скобках — количество символов непрочитанной цепочки, используемых анализатором для принятия решения на каждом шаге.

Пусть задана некоторая контекстно-свободная грамматика [Белоусов, Ткачев, 2006]. Рассмотрим произвольную

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

Наиболее популярны два метода разбора [Борисенко]:

• рекурсивный разбор;

• разбор, использующий стек и конечный автомат (часто употребляется термин "автомат с магазинной памятью").

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

Состояние LR-процесса в любой момент времени описывается его стеком и непрочитанной частью входной цепочки. Стек LR-процесса хранит обычные символы и метасимволы. Удобно представлять стек "повернутым навстречу входной цепочке", как показано на рис. 3.

Рис. 3. Схема стека LR-процесса

Стек LR-процесса представляет собой слово, состоящее из терминалов и нетерминалов, которое наращивается с правого конца. В любой момент времени при выполнении LR-процесса возможны только два действия: сдвиг или свертка (примеры даны на рис. 4-5).

Рис. 4. Пример операции сдвига

Правило: Q —> cad

Рис. 5. Пример операции свертки

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

Перейдем к построению конечного автомата. Рассмотрим сначала более простой случай — LR(0)-разбор.

1.2 LR(0)-анализаторы

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

Грамматика называется LR(0)-

грамматикой, если каждое состояние ее LR(0)-автомата, содержащее пункт вида [А^а], состоит из единственного пункта [Белоусов, Ткачёв, 2006]. Пример конечного автомата для LR(0)-парсера представлен на рис. 6.

S' —* S 5-1 . SS (L) . id

4 1

S'-t S S

t

Копечиое состоя [[не

id 3 id.

L-..S

L — L,5

S-t

S-1 . id

5 5 1

L-tL, . S

S-.

S -s id

5

S-(L).

L —* L-,

) 6 \ p

S-tC'LJ'.

S.

Грамматика:

S -»( L ) | id L -f S | L, S

CS 412/413 Spring 2006

Radu Rugina - introduction to Compilers. Lecture 9

Рис. 6. Пример конечного автомата для LR(0)-napcepa

1.3 SLR(1)-анализаторы

На практике чаще всего используются промежуточные между LR(0) и LR(1) методы, известные под названиями SLR(1) и LALR(1).

Грамматика называется SLR(1)-грамматикой (Simple LR(1)), если в таблице разбора, построенной соответствующим алгоритмом, нет конфликтов (т.е. в каждой клетке не более одной записи).

Данный анализатор почти не имеет практического применения из-за узкого класса разбираемых грамматик [O'Donnell, 2008], именно поэтому в некоторых случаях SLR-разбор может выдать неправильный результат. В таких случаях используют более сложные методы, такие как LR(1) и LALR(1)-разбор.

1.4 LR(1)-анализаторы

Рассмотренный ранее SLR(1)-подход использует не всю имеющуюся информацию при определении возможности свертки. Алгоритм LR(1) учитывает тот факт, что при проверке текущего состояния стека и правила при данном символе на возможность свертки возможно выполнение обоих условий, причем свертка при текущем стеке и очередном символе невозможна. Именно поэтому основным отличием LR^-разбора от SLR-разбора является использование

предпросмотра (англ. lookahead) символов.

Таким образом, основной принцип работы LR(1)-анализатора в том, чтобы не производить некорректные свертки. Для этого мы добавим в грамматику второй компонент — терминальный символ, [A ^ а • в, a].

1.5 LALR(1)-aнaлизaторы

LALR(1)-анализатор (LA — англ. lookahead) является улучшением LR(0)-анализатора, позволяющий сохранять наиболее подходящие ветви разбора для устранения неоднозначности грамматик.

Анализатор LALR(1) занимает

промежуточное положение между LR(0)- и LR(1)-парсерами: он чуть более требователен к объему памяти, чем LR(0), но в то же время является менее мощным, чем LR(1).

Все грамматики, которые способны разобрать LR(0)-парсеры, может

анализировать и LALR(1)-парсер. В то же время, все грамматики, с которыми может работать LALR(1)-парсер, поддаются анализу с помощью LR(1), но не наоборот.

1.6 GLR-анализаторы

GLR-анализатор (англ. Generalized Left-to-right Rightmost derivation parser) — обобщённый восходящий магазинный анализатор, расширенный алгоритм LR-парсера, предназначенный для разбора по недетерменированным и неоднозначным грамматикам. Теоретическая база была заложена Бернардом Лэнгом [Lang, 1974], впервые такой парсер описал Масару Томита [Tomita, 1984]. Такой парсер также называют «параллельным парсером», поскольку он строит деревья разбора. Создавался он с целью анализа текстов на естественных языках, с недетерминированностью и

неоднозначностью которых LR-парсер не вполне справляется.

Поскольку GLR-парсеры обрабатывают различные ветви разбора параллельно, они используют более сложную стековую структуру, нежели LR-парсеры. Вместо одного линейного стека используется стек с графовой структурой (GSS — англ. graph-structured stack), который позволяет эффективно хранить различные ветви разбора, которые помечаются неактивными по мере сдвига входных токенов или символов [Tomita, 1988]. Все неактивные ветви должны быть восстановлены в случае повторного посещения старого состояния, из чего следует задача применения поиска с возвратом. Существуют решения, основанные на эвристиках и позволяющие оптимизировать работу парсера в такой постановке, сокращая объём хранимой информации [De Jonge, 2014].

У классического GLR-анализатора есть ряд недостатков. В частности, он не выходит из скрытой левой рекурсии [Johnstone et al., 2004], что актуально для языков программирования; предложены решения по этому пункту [Visser, 1997; Johnstone et al., 2004, Johnstone et al., 2006]. При ошибках разбора параллельно с другими ветвями, в которых происходят нормальные продукции, предлагаются варианты анализа ошибок, обходящие дерево разбора в обратном направлении в поисках точек, в которых производился выбор [De Jonge, 2014]. Отдельно в этом случае рассматривают различия между точкой возникновения

Табл. 1

фактической ошибки и точкой её обнаружения [Degano, Priami, 1995].

Существует ряд модификаций GLR-парсера. Так, в [McPeak, Nekula, 2004] предлагается гибридный автоматический метод, осуществляющий выбор между LR- и GLR-парсерами по контексту, в зависимости от анализа цепочки токенов.

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

2 Сравнение анализаторов

Обобщая характеристики анализаторов, представленных выше, можно составить сравнительную таблицу (табл. 1).

Как следует из таблицы, для разработки систем анализа текста, не требующих обработки сложных грамматик, можно воспользоваться такими парсерами, как LR(0) и SLR(1). В случае необходимости поддержки более сложных грамматик или повышения точности, потребуется реализовать LALR(1)-или LR(1)-парсеры, однако в этом случае система станет более требовательной к оперативной памяти.

Для анализа формальных языков подходят парсеры семейства LR. При анализе естественных языков требования к парсеру возрастают, это связано в том числе с неоднозначностями в языке [Клышинский, 2015]. В этом случае для анализа текстов лучше подходит семейство GLR-парсеров.

Сравнительная таблица характеристик анализаторов

Название анализатора LR(0) SLR(1) LALR(1) LR(1) GLR

Кол-во символов непрочитанной 0 1 1 1 произвол

цепочки для принятия решения ьное

Поддерживаемые грамматики LR(0) LR(0) SLR(1) LR(0) SLR(1) LALR(1) LR(0) SLR(1) LALR(1) LR(1) LR(0) SLR(1) LALR(1) LR(1) GLR

Количество состояний малое больше, чем у LR(0) такое же, как у SLR(1) большое большое

Размер таблицы LR-разбора малый малый средний большой большой

Использует предпросмотр нет нет да да да

Пригоден для анализа текстов на да да да да да

формальных языках

Пригоден для анализа текстов на флективно-формальных языках нет нет да да да

Способен разрешать недетерменированность и неоднозначность естественных языков нет нет нет нет да

3 Практическое применение GLR-анализаторов

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

Отличным примером GLR-парсера является Томита-парсер, который

используется в различных сервисах Яндекса [Крылова, 2015]: для извлечения фактов из новостных текстов, получения информации из мнений и отзывов, фильтрации объявлений. Также GLR-парсеры позволяют получать связи между объектами (отношения между персонажами в художественной литературе), находить изменения в законодательстве РФ, определять тональность текстов.

Заключение

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

• сложность текста;

• объем анализируемой информации;

• бюджет на разработку;

• время, отведённое на реализацию.

Именно эти факторы могут стать

ключевыми при выборе алгоритма для разработки.

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

Подробно рассмотрено семейство LR-анализаторов. Результаты сравнительного анализа сведены в таблицу. Рассмотрены различные модификации GLR-парсеров.

Список литературы

[Белоусов, Ткачев, 2006] Белоусов А.И., Ткачев С.Б. Дискретная математика: Учеб. для вузов / Под ред. В.С. Зарубина, А.П. Крищенко. — 4-е изд., исправл. — М.: Изд-во МГТУ им. Н.Э. Баумана, 2006. — 744 с. (Сер. Математика в техническом университете; Вып. XIX).

[Большакова и др., 2011] Большакова Е.И., Клышинский Э.С., Ландэ Д.В., Носков А.А., Пескова О.В., Ягунова Е.В. Автоматическая обработка текстов на естественном языке и компьютерная лингвистика. Учебное пособие.

— М.: МИЭМ, 2011.

[Борисенко] Борисенко В.В. Лекция 14: LR-разбор. URL:

http://math.msu.su/~vvb/BMSTU/lectLR.html (дата обращения 23.03.2017).

[Борисова, Канищева, 2012] Борисова Н.В., Канищева О.В. // Бионика интеллекта, № 2, 2012. — С. 89-94.

[Клышинский и др., 2015] Клышинский Э. С., Логачева В. К., Нивре Й. Распределение неоднозначных слов в некоторых европейских языках // Труды Международной научной конференции "Корпусная лингвистика-2015".

— СПб.: Издательство СПбГУ, 2015. — С. 270277.

[Терехов и др., 2001] Терехов Ан.А., Вояковская Н., Булычев Д., Москаль А. Разработка компиляторов на платформе .NET. — СПб.: Кафедра системного программирования СПбГУ, 2001.

[De Jonge, 2014] De Jonge M. Language-parametric techniques for language-specific editors. Doctoral thesis. Delft University of Technology, Amsterdam, 2014.

[Degano, Priami, 1995] Degano P., Priami C. Comparison of syntactic error handling in LR parsers // Software: Practice and Experience, vol. 25 (6). — New York: John Wiley & sons, Ltd., 1995. — Pp.657-679.

[Johnstone et al., 2004] Johnstone A., Scott E., Economopoulos G. Generalized parsing: some costs // LNCS 2985. — Berlin: Springer, 2004. — Pp. 89-103.

[Johnstone et al., 2006] Johnstone A., Scott E., Economopoulos G. Evaluating GLR parsing algorithms // Science of Computer Programming, vol. 61 (3), August 2006. — Amsterdam: Elsevier, 2006. — Pp. 228-244.

[Lang, 1974] Lang B. "Deterministic techniques for efficient non-deterministic parsers". Automata,

Languages and Programming, 2nd Colloquium. Loeckx, J., ed. LNCS 14. - Saarbrücken: Springer, 1974. — Pp. 255-269. doi: 10.1007/3-540-06841-4_65. ISSN 0302-9743.

[McPeak, Nekula, 2004] McPeak S., Nekula G.C. Elkhound: a fast, practical GLR parser generator // LNCS 2985. — Berlin: Springer, 2004. — Pp. 7388.

[O'Donnell, 2008] O'Donnell M.. Compilers, 2008. URL:

http://arantxa.ii.uam.es/~modonnel/Compilers (дата обращения 23.02.2017).

[Tomita, 1986] Tomita M. Efficient parsing for natural language. — Boston: Kluwer Academic Publishers, 1986.

[Visser, 1997] Visser E. Syntax definition for language prototyping. PhD thesis, University of Amsterdam, 1997.

[Крылова, 2015] Крылова И., Яндекс. Tomita parser. ВШЭ, 20.04.2015.

URL:

https://cs.hse.ru/data/2015/04/27/1098338342/Tom

ita_hse_20_04_15.pdf

(дата обращения 03.03.2017).