Рейтинг темы:
  • 0 Голос(ов) - 0 в среднем
  • 1
  • 2
  • 3
  • 4
  • 5
LL(1) грамматики
#1
Возникла необходимость сделать лексический и синтаксический анализатор "простого" класса. Изучив возможные варианты построения, более простыми и надежными(по сравнению с LR) показались LL(1) грамматики. Сказано - сделано, сходу было построено выделение лексем(flex), разобран заголовок класса, дело дошло до тела, и столкнулся с неприятностью. Для того, чтобы обработать объявления переменных, и вовремя перейти к обработке следующей секции - нужно предугадать, когда будет объявлена последняя переменная. Каким образом можно это сделать?
Открыть спойлер

Открыть спойлер
Ответ
#2
Может я неправильно понял, но при объявлении используются ключевые слова для типа данных? Может искать в строке название и есть оно не найдено то закрывать объявляющую секцию?
Ответ
#3
Zubastic Написал:Может я неправильно понял, но при объявлении используются ключевые слова для типа данных? Может искать в строке название и есть оно не найдено то закрывать объявляющую секцию?

В таком случае это будет неверно для переменных, объявленных внутри функций, (будет искаться следующая секция, что ошибочно, так как уже идет обработка этой секции)
Ответ
#4
может что-то такое
1
если на входе терминал(int,float, имя_класса и тд) -> делаем цикл (больше,маленькие буквы, цифры) пока не знак "=" -> цикл по цифрам до ";" -> проверяем, есть ли еще терминалы -> начали новый анализ -> иначе нету переменных.

зы. "Для того, чтобы КС-грамматика была LL(1)-грамматикой, необходимо, чтобы множества выбора для правил с одинаковыми левыми частями не пересекались, т.е. не имели общих терминальных символов." - будешь ли делать такую проверку?)
Ответ
#5
учусь Написал:может что-то такое
1
если на входе терминал(int,float, имя_класса и тд) -> делаем цикл (больше,маленькие буквы, цифры) пока не знак "=" -> цикл по цифрам до ";" -> проверяем, есть ли еще терминалы -> начали новый анализ -> иначе нету переменных.

зы. "Для того, чтобы КС-грамматика была LL(1)-грамматикой, необходимо, чтобы множества выбора для правил с одинаковыми левыми частями не пересекались, т.е. не имели общих терминальных символов." - будешь ли делать такую проверку?)


То есть после каждого ';' в секции parameters проверять следующий терминал (float, int)/handlers/end_of_class, и в зависимости от этого терминала переходить к дальнейшему разбору?
Ответ
#6
Нашёл кусок грамматики про объявление переменных:

<def> -> int var <def_end>
<def_end> -> ; | , var <def_end> | <init> ;
<init> -> = <com_expr> ;
<com_expr> -> <expr> <oper> <com_expr> | ;
<oper> -> ) | + | - | / | * | < | > | <= | >= | == | != | && | ||
<expr> -> var | const | ( <expr>


Вот так транслятор выглядел Smile

Давай таблицу разбора делай и вперёд.
Ответ
#7
мне тоже кажется, что лучше сначала на бумажке написать полную грамматику. потом применить алгоритмы(устранение недостижимых, рекурсивных и тд) и получить LL(1), а то бесконечные циклы вылезут. но это мое мнение.

нашел самописные реализации алгоритмов:
1
Ответ
#8
Array, учусь, А может LALR(1) лучше подойдет для такого рода разбора?

Добавлено через 3 часа 53 минуты
Всем спасибо, особоенно Array и учусь. Успешно построил грамматику с использованием LALR(1).
Ответ
#9
Думаю, что Вашу проблему можно было бы решить LL(1)-парсером с использованием Look Ahead алгоритма. Собственно, yylex поддерживает такую возможность.
Вообще, восходящие алгоритмы для парсеров более приоритетны, т.к. класс разбираемых грамматик нисходящих алгоритмов является подклассом для множества разбираемых грамматик восходящих алгоритмов.
// aka Deft
Ответ
#10
Yorie Написал:Думаю, что Вашу проблему можно было бы решить LL(1)-парсером с использованием Look Ahead алгоритма.

Camelion Написал:Всем спасибо, особоенно Array и учусь. Успешно построил грамматику с использованием LALR(1).

Собственно так и было сделано.

P.S. Некропост наказывается по закону.
Fortuna - non penis, in manus non recipe.
Ответ


Перейти к форуму:


Пользователи, просматривающие эту тему: 2 Гость(ей)