185 похожих чатов

@Zukaboo спасибо за очень важные замечания. А как вам такой

вариант?
______________
Очень часто разбор текста и построение из него дерева разбора (parse tree) удобно разбить на две фазы. В первой фазе используется близкая к регулярной, но не регулярная грамматика (грамматика, описываемая регулярными выражениями), во второй фазе - контекстно-свободная. Это разбиение, в принципе, не обязательно, но крайне удобно и быстро.

В первой фазе текст пропускается через некоторую программу (*лексер*), которая читает текст программы посимвольно (UTF8 или ASCII символы), составляя из этих символов слова (так называемые tokens) используя регулярные выражения. Грамматика языка, разбираемого лексером отличается от регулярной тем, что в случае альтернативы выбирается не первый подходящий вариант, а тот, что даёт наиболее длинный префикс (жадный выбор). Важно, что получающееся дерево разбора *вырождено*, то есть, это просто список, и, таким образом, поток символов ASCII превращается в поток token'ов. С формальной точки зрения и то, и другое - _символы_, но разных языков.
_______________

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

11 ответов

15 просмотров

> Это разбиение, в принципе, не обязательно, но крайне удобно и быстро. Нет, это разбиение строго обязательно для разбора подавляющего большинства практически используемых ЯП с помощью CFG (и parser generators, особенно широко используемых LALR / LR), т.е. сделать это без него тупо невозможно. > составляя из этих символов слова (так называемые tokens) используя регулярные выражения. Нет, чаще всего lexer-ы используют не только регулярные выражения (в том числе в этом и суть их применения). Тут уже приводили примеры — мне кажется, или Вы их все проигнорировали? :( > Грамматика языка, разбираемого лексером По-моему, это вообще не разбор. Если открыть любой учебник по parsers (или формальной лингвистике), или даже погуглить определение этого понятия (и того, что такое recognition, вообще) — очевидно, что то, что делают lexers — это, в общем (практическом!) случае, не он: "Parsing is the process of structuring a linear representation in accordance with a given grammar." "The task of parsing is to reconstruct the derivation tree (or graph) for a given input string." "To parse a string according to a grammar means to reconstruct the production tree (or trees) that indicate how the given string can be produced from the given grammar." "Parsing, syntax analysis, or syntactic analysis is the process of analyzing a string of symbols, either in natural language, computer languages or data structures, conforming to the rules of a formal grammar. " Обратите внимание, что во всех определениях есть строка символов, и parsing определяет, какое дерево (или деревья, или графы) разбора соответствуют ей целиком, понимаете? Т.е. даже грамматика языка, получаемого последовательными вызовами gettoken() для строки (до победного конца), хотя эта функция использует исключительно longest DFA matching — не регулярная! > Важно, что получающееся дерево разбора Там может вообще не получаться ни дерева разбора, ни потока или массива tokens, в практическом случае. Поступать так на практике для одного языка не принято... но про lexer hack (из C) все слышали, вроде? ;) А при language composition (т.е. например, "смешивании" C и SQL в один язык) с использованием lexers сами выделяемые tokens будут контекстно-зависимы, т.е. модель "поток/массив токенов" тут неприменима. > то есть, это просто список, и, таким образом, поток символов ASCII превращается в поток token'ов. Но это, в самом деле, распространённая "абстрактная" модель для [упрощения изложения темы] parsing. Только к практике она относится далеко не всегда. > Поскольку это всё равно разбор, пусть и экзотического неназванного класса грамматик, это парсер. Для некоторых случаев это "сойдёт", см. выше.

Yaroslav Schekin
> Это разбиение, в принципе, не обязательно, но кр...

Вы очень долго распространялись на тему, чем лексеры НЕ являются, но чем же они являются и как определяются осталось совершенно непонятным, как минимум мне.

Konstantin-Romanov Автор вопроса
Yaroslav Schekin
> Это разбиение, в принципе, не обязательно, но кр...

1. Спасибо за упоминание того, что учёт контекста в лексере позволяет убрать учёт контекста в парсере. Александр упоминал про контекстно-зависимые грамматики второй фазы, но я забыл это вставить. 2. Да, в лексерах используют не только регулярные выражения. Я сознательно замёл это под ковёр. Обычно это всё-таки делает малая доля правил. 3. > По-моему, это вообще не разбор. Список лексем - это тоже дерево, просто очень частный вид. Грамматика, упрощённая вот - регулярная + жадность. 4. > Там может вообще не получаться ни дерева разбора, ни потока или массива tokens, в практическом случае. Ну конкретно flex не может выдать ничего другого, кроме потока, на вход парсера.

Alexander Chichigin
Вы очень долго распространялись на тему, чем лексе...

Это, в общем случае, такая штука, которая для текущей (или заданной) позиции во входном потоке (почти всегда — потоке символов), и, возможно, внутреннего (хранимого) состояния и передаваемых ему parser-ом параметров возвращает очередной token.

Konstantin Romanov
1. Спасибо за упоминание того, что учёт контекста ...

> Обычно это всё-таки делает малая доля правил. "Обычно" Вы без этого почти ни один практический язык не разберёте. Т.е. Вы ребёнка под ковёр замели выплеснули вместе с водой. ;( > Список лексем - это тоже дерево, просто очень частный вид. Если он вообще есть. Покажете нам, как создать "список лексем" для типичного LALR-parser для C, не используя parser? > Ну конкретно flex не может выдать ничего другого, кроме потока, на вход парсера. Вы вообще не поняли, что я имел в виду. :( То, что выдаёт flex на вход parser, может зависеть (хоть целиком определяться!) теми параметрами, с которыми его вызывает parser, а не входным потоком символов, понимаете?

Yaroslav Schekin
> Это разбиение, в принципе, не обязательно, но кр...

> т.е. сделать это без него тупо невозможно integer = digit | digit integer digit = '0' | … Не вижу невозможности.

Konstantin-Romanov Автор вопроса
suhr
> т.е. сделать это без него тупо невозможно integ...

Вопрос с жадностью остаётся открытым.

Konstantin Romanov
Вопрос с жадностью остаётся открытым.

Этот вопрос появляется при лексинге, а не при разборе одной огромной грамматики.

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

Похожие вопросы

Обсуждают сегодня

а зачем этот вопрос для удаления из чата?
Mёdkinson Medvezhkin
63
Эх кто-то пришел и весь праздник испортил :( You need complex FBX scene importing setup to change things on import? good luck with that. You need navigation and pathfinding? g...
Serg Gini
5
Всем привет! Подскажите. Я написал приложение на Delphi 10.2 Tokyo под Windows 10. И передо мной стал вопрос о том чтобы сделать это приложение кроссплатформенным (под Linux и...
Дмитрий Завгородний
24
Какого хера? /Sources/App/Modules/User/Models/UserLinkApple.swift:21:20: warning: stored property '_id' of 'Sendable'-conforming class 'UserLinkApple' is mutable @ID(...
Alexander Sherbakov
11
У тебя в конфиге нигде нет deny all; или вообще любого deny?
Alexander Sherbakov
10
Почему стало ломаться на D11? "739002.86400000' is not a valid timestamp" function IncDateTime(aStamp:TTimeStamp;aKind:TTriggerKind;aInterval:Integer):TDateTime; //aStamp = 2...
Катерина Свиридова
8
Привет всем. Подскажите где можно посмотреть, какая версия электрон, поддерживает версии windows? Некий changelog. Мне бы желательно, поддержку 7,8,10... latest, как понимаю и...
Anonym Squad
21
Портфолио: Зовут меня Александр, мне 36 лет. Город Пушкино. Общий рабочий стаж: ~14 лет Уровень квалификации: Senior Full-stack developer Где прочесть мой код? https://github....
Magic
10
думаешь я не смогу также сделать? мне это просто не удобно
int 💳 𝙖𝙞𝙧 𝙗𝙞𝙜 𝙗𝙤𝙗 🔫 check bio / spam block / AFK / nohello.com / GMT+3
9
Ребят, чет я уже не догоняю... Крч в коде на асм там происходит нечто вроде a+число (a+1, a+2 и т.д.). Но почему строка lea ecx, [edx+1] работает как a+1?? В edx берется адрес...
Alan 🔝 Бэброу
4
Карта сайта