Здравствуйте, Sinclair, Вы писали:
M>>И еще чтобы синтаксис был вехде единым. PCRE настолько распространены, что никто и не думает, что писать можно и по другому.
Да ладно? Посмотри например регэксы в поиске VS. Сильно удивишься.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Здравствуйте, Klatu, Вы писали:
M>>>И еще чтобы синтаксис был вехде единым. PCRE настолько распространены, что никто и не думает, что писать можно и по другому.
K>Да ладно? Посмотри например регэксы в поиске VS. Сильно удивишься.
Кто-то явно хотел ответить не мне
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, netch80, Вы писали:
VD>>>Уверен, что появись указанные бэкэнды у тебя найдутся новые отговорки.
N>>С чего бы вдруг?
VD>Из опыта. Танцоры которым что-то мешает обычно после удаления того что мешает все равно находят что-то что оправдывает трудность танцев.
Ага, кому-то вот язык программирования мешает шедевры производить на свет
Здравствуйте, VladD2, Вы писали:
J>>Предикат — это совсем не то, что ".*". Предикаты и в регэкспах есть (твой пример с комментарием можно написать в регэкспе вот так:
J>>J>>/\* ((?! \*/ ) . )* \*/
J>>
J>>непонятно, зачем, правда, когда есть более простой путь, выше).
VD>Ну, вот и сравни читаемость. Плюс не забывай, что для ПЕГ-а есть алгоритм обеспечивающий разбор указанной грамматики за линейное время, а для регексов такого нет.
А что, разве указанный jazzer'ом регексп:
/\* ((?! \*/ ) . )* \*/
работает не линейное время?
VD>Экспоненту получить вообще сложно. Хреновые показатели будут на грамматиках с большими общими префиксами и на грамматиках чей класс очень сильно и постоянно отличается от LL(1). Короче, на грамматиках для разбра которых нужны частые и глубокие откаты.
VD>Вот только 99% языков как раз имеют почти LL(1)-грамматики. Например, C# имеет грамматику которую можно на 95% переписать в LL(1). Но там есть сложности вроде эвристик связанных с оператором приведения типов (конфликтующим со скобками и вызовом функций), оператор ?: и ? в налабл-типах и некоторое количество дурной фигни. PEG позволяет разрулить эти неоднозначности с помощью предикатов (благо они ничем не ограничены), а вот у автоматных парсеров эти эвристики вызывают ужасные проблемы.
Читаю я это и задумался. Написал бы кто-нибудь туториал по тому, с чего начинать описывать грамматику уже существующего языка на PEG'е. Потому что вон тот же C#. Огромный синаксис. С чего начать? Как разруливать неизбежные конфликты? Ну и т.п.
Здравствуйте, Mamut, Вы писали:
M>Читаю я это и задумался. Написал бы кто-нибудь туториал по тому, с чего начинать описывать грамматику уже существующего языка на PEG'е. Потому что вон тот же C#. Огромный синаксис. С чего начать?
С базовых правил (тех что в спецификации называется в разделе "Lexical structure"). Далее по спецификации от пространств имен и до "лисьтев" (выражений и т.п.).
PEG имеет очень много общего с написанием парсеров вручную методом рекурсивного спуска. Так что если этот метод знаком, то освоить написание PEG-грамматик труда не составит.
M>Как разруливать неизбежные конфликты? Ну и т.п.
Отпарсить реальные (корректные) исходники и получить неверный разбор. Далее разобраться в чем проблема и подумать как устранить ее с помощью предикатов. Предикаты вещь настолько мощная, что позволяют разрулить любой конфликт если только он не приводит к появлению неоднозначной грамматики или контекстно-зависимой грамматике (да и некоторые КЗ-вещи тоже позволяет разрулить).
M>>Читаю я это и задумался. Написал бы кто-нибудь туториал по тому, с чего начинать описывать грамматику уже существующего языка на PEG'е. Потому что вон тот же C#. Огромный синаксис. С чего начать?
VD>С базовых правил (тех что в спецификации называется в разделе "Lexical structure"). Далее по спецификации от пространств имен и до "лисьтев" (выражений и т.п.).
Эх, не всегда есть такой раздел
VD>PEG имеет очень много общего с написанием парсеров вручную методом рекурсивного спуска. Так что если этот метод знаком, то освоить написание PEG-грамматик труда не составит.
Ага, буду ковырять.
M>>Как разруливать неизбежные конфликты? Ну и т.п.
VD>Отпарсить реальные (корректные) исходники и получить неверный разбор. Далее разобраться в чем проблема и подумать как устранить ее с помощью предикатов. Предикаты вещь настолько мощная, что позволяют разрулить любой конфликт если только он не приводит к появлению неоднозначной грамматики или контекстно-зависимой грамматике (да и некоторые КЗ-вещи тоже позволяет разрулить).
Спасибо за толчок в нужном направлении
M>Эх, не всегда есть такой раздел
двигайся стандартно — сверху вниз.
берешь реальные тексты и пытаешься их распарсить — для начала только общую структуру, потом спускаешься ниже и т.д.
пример, допустим необходимо распарсить C# — большая часть структуры описывается с помощью '{', '}'. попробуем распарсить эту структуру
первое приближение грамматики
file := block-body;
block-body := (другое? block)* другое?;
block := '{' block-body '}';
другое := .+;
все хорошо, но есть конфликт, peg — жадный, поэтому терм 'другое' съест и открывающие скобки, и закрывающие, которые нужны правилу block.
разрешим конфликт — запретив терму 'другое' хавать скобки
file := block-body;
block-body := (другое? block)* другое?;
block := '{' block-body '}';
другое := (!('{' / '}') .)+;
работает, но ломается, если есть непарные скобки в комментарии или литерале?
добавляем их
line-comment := '//' (!line-break .)* line-break;
multi-line-comment := '/*' (!'*/' .)* '*/';
literal := ('""' (!'""' .)* '""') / (""'"" (!""'"" .)* ""'""); //как пример, в шарпе чуть другие правила записи литерала
line-break := ([\r][\n]) / [\r] / [\n];
модифицируем правило другое и получаем грамматику:
file := block-body;
block-body := (другое? block)* другое?;
block := '{' block-body '}';
другое := (!('{' / '}') line-comment / multi-line-comment / literal / .)+;
line-comment := '//' (!line-break .)* line-break;
multi-line-comment := '/*' (!'*/' .)* '*/';
literal := ('""' (!'""' .)* '""') / (""'"" (!""'"" .)* ""'""); //как пример, в шарпе чуть другие правила записи литерала
line-break := ([\r][\n]) / [\r] / [\n];
эта грамматика уже устойчивая ко всем видам C#-файлов (если ничего не забыл), и позволяет уточнять грамматику дальше в нужном направлении — в зависимости от задачи.
схема изменения грамматика стандартная: формулируется новое правило, вставляется "вызов" в нужное место, есть есть конфликт — остальным правилам явно запрещается хавать символы, которые нужны новому правилу.
также грамматика периодически рефакторится, чтобы быть менее громоздкой и более быстрой для исполнения
данный пример писал в браузере и не тестил, поэтому там есть ряд неточностей.