Re[9]: парсер LR1 и С
От: maxkar  
Дата: 09.07.22 08:38
Оценка: 158 (3)
Здравствуйте, VVVa, Вы писали:

VVV>Здравствуйте, maxkar,

VVV>читаю драконью книгу и интернет
Управжнения из книги делаете? Некоторые вещи становятся понятнее, когда сделаны руками. Это как ездить на велосипеде — можно выучить много теории, но она никогда полностью не заменит практику.

VVV>https://neerc.ifmo.ru/wiki/index.php?title=LR(1)-%D1%80%D0%B0%D0%B7%D0%B1%D0%BE%D1%80

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

VVV>както с SLR ещё понятно а вот LR1 или LALR совсем не догоняю ...

Со слайдами выше должно стать получше. Вообще все эти вариации — уточнение и детализация правил разбора. LR(0) конфликтов/неоднозначностей не допускает. SLR допускает, но использует очень простой алгоритм разрешения. Например, если на стеке [..., a, b, c], в потоке следующий символ d и есть правила D -> abc, то свертка будет, если где-нибудь в грамматике за D может быть терминал d. "Где-нибудь" — это очень "слабое" условие. Может быть, контекст (символы слева) предполагают контекст, в котором за D не может следовать d. LR(n) как раз разрешает эту неоднозначность. Он к каждому правилу приписывает "контекст". В данном случае контекстом является следующий терминал (или несколько символов в случае LR(k)), которые могут следовать за состоянием (точнее, правилом) в каком-то валидном разборе. Т.е. [A->b•Cd, x] — это разбор нетерминала A (мы прочитали b и должен следовать нетерминал C) в контексте, когда после нетерминала A должен следовать терминал x. В данном случае для разбора C контекст A не очень важен — за C (в данном контексте) может следовать только d. Но если вдруг у нас есть правила вида [A->b•C, x] или [A->b•CD, x] (где D может порождать пустую цепочку), то x может определять свертку в C (в слайдах есть пример, это LR(1) не являющийся LALR(1)). LR-алгоритм является формализацией этой идеи.

LALR(1) — оптимизация LR(1). Она уменьшает количество состояний, но при этом теряет точность. Разницу можно посмотреть в том же bison. Он по умолчанию генерирует LALR но можно попросить делать LR.

VVV>может есть чтото по понятнее?

Привел выше слайды, с ними должно быть полегче. А вот что есть материалы сильно понятнее — сомневаюсь. Дракон и слайды для меня были достаточно понятны. Я не уверен, что можно где-то упростить объяснения. Практика (упражнения) могут помочь. Ну и дальше нужно смотреть, что именно у вас вызывает проблемы. Например, вы можете написать, какие задачи у вас вызвали сложности? Или что в процессе построения конечных автоматов не получилось? Или какую-то другую конкретику? Без обратной связи здесь сложно.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.