[Ответить в тред] Ответить в тред

03/04/16 - Набор в модераторы 03.04 по 8.04
26/03/16 - Конкурс: Помоги гомункулу обрести семью!
15/10/15 - Набор в модераторы 15.10 по 17.10



[Назад][Обновить тред][Вниз][Каталог] [ Автообновление ] 28 | 3 | 10
Назад Вниз Каталог Обновить

Sup, /pr/. Пишу свой генератор Аноним 03/06/16 Птн 01:54:36  760464  
14649080770620.jpg (61Кб, 1021x710)
Sup, /pr/. Пишу свой генератор парсеров на базе parsing expressions. И у меня возникла проблема: как разрешать левую рекурсию?

Что у меня есть сейчас: DSL для описания грамматик, я могу его распарсить и построить по нему AST, могу пидорасить это AST, как угодно, могу построить по этому AST простенький recursive-descent parser.

В принципе, мне этого уже хватает, но хочу сделать еще удобнее: в частности, я не хочу разруливать сам левую рекурсию. То есть, я хочу записать что-то такое:

[code]
expr <-
expr '+' expr [priority 10] /
expr '' expr [priority 20] /
number ;
[/code]

А мой генератор чтоб сам преобразовывал его во что-нибудь такое:

[code]
expr <-
expr1 ('+' expr1)+ /
expr1 ;
expr1 <-
expr2 ('
' expr2)+ /
expr2 ;
expr3 <-
number ;
[/code]

Проблема в том, что это очень частный случай левой рекурсии. Это самое expr может быть зарыто еще в десятке правил, которые вызываются в самом expr. Так вот, как мне так перепидорасить AST моей грамматики? Или, может, генерируемый парсер как-то доработать (мемоизацию какую-нибудь прикрутить)?
Аноним 03/06/16 Птн 01:57:37  760465
>>760464 (OP)
Бля, разметка проебалась. Вот, короче: https://spit.mixtape.moe/view/8f4601c1 .
Аноним 03/06/16 Птн 03:03:19  760473
>>760464 (OP)
https://ru.wikipedia.org/wiki/Yacc
https://ru.wikipedia.org/wiki/Lex
Аноним 03/06/16 Птн 09:12:19  760509
14649343393410.png (372Кб, 340x500)
>>760464 (OP)
Дрэгонбук тебе в помощь, там все написано.
https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%82%D0%BE%D1%80%D1%8B:_%D0%BF%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF%D1%8B,_%D1%82%D0%B5%D1%85%D0%BD%D0%BE%D0%BB%D0%BE%D0%B3%D0%B8%D0%B8_%D0%B8_%D0%B8%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B
Аноним 03/06/16 Птн 11:08:04  760545
>>760473
>>760509
А вот и боты подтянулись. Но все равно отвечку.

> parsing expressions
> recursive-descent
Аноним 03/06/16 Птн 17:55:27  760761
>>760464 (OP)
Первая ссылка из гугла: https://github.com/orlandohill/peg-left-recursion
Аноним 03/06/16 Птн 18:23:54  760777
Лавир младший?
Аноним 03/06/16 Птн 19:58:49  760831
>>760761
Почитал. По сути, он предлагает преобразовывать `A <- A a / B` в `A <- B a`. Я примерно это же и думал делать. Но это как-то паскудно выглядит, алсо, я не разобрался с областями видимости в семантических действиях. `A <- A a { do_this } / B { do_that }` преобразовывается в `A <- (B a { ??? }`. Или мне надо просто отдохнуть и врубиться еще раз.
Аноним 03/06/16 Птн 20:00:25  760834
>>760831
Да блин!

A <- A a / B преобразовывать в A <- B a star.

A <- A a { do_this } / B { do_that } преобразовывать в A <- B (a { ??? }) star.
Аноним 03/06/16 Птн 21:06:50  760866
>>760545
Дегенерат, еще в старом издании дрэгонбука все написано и про рекурсивный спуск, и про разрешение этой твоей левой рекурсии. Но зачем тебе книги - лучше на двоще покрасоваться, пусть пионэры поахают.
Аноним 03/06/16 Птн 22:14:36  760913
>>760866
О, точно! И там тоже самое написано. Значит, я движусь в верном направлении.

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

expr = expr '+' expr { piece1 } / expr 'x' expr { piece2 } / number ;

И там вроде не написано про левую и правую ассоциативность, но это уже тривиально делается.
Аноним 04/06/16 Суб 10:27:33  761089
>>760913
>expr = expr '+' expr { piece1 } / expr 'x' expr { piece2 } / number
Запиши нормально в ABNF грамматику, не понимаю твою писанину.
Аноним 04/06/16 Суб 10:34:46  761093
>>761089
expr = expr "+" expr / expr "x" expr / 1DIGIT ;

Это без семантических действий. А вот с семантическими действиями:

expr = expr "+" expr { do_this } / expr "x" expr { do_that } / 1
DIGIT ;
Аноним 04/06/16 Суб 10:35:48  761094
>>761093
Ну блядство же!

expr = expr "+" expr / expr "x" expr / 1✱ DIGIT ;

Это без семантических действий. А вот с семантическими действиями:

expr = expr "+" expr { do_this } / expr "x" expr { do_that } / 1✱ DIGIT ;
Аноним 04/06/16 Суб 11:09:56  761111
>>761094
Твои ололо семантические действия относятся уже не к грамматике, а к узлу оператора в дереве разбора, полученном грамматикой из входящего текста. Или у тебя полная каша в голове, или ты не умеешь выражать свои мысли.

Чтобы избавиться от левой рекурсии, тебе нужно ввести новые нетерминалы expr1, которые не будут начинаться с expr, а также воспользоваться эпсилон-продукцией eps:

expr = digit expr1
expr1 = "+" expr / "x" expr / eps
digit = 1 &#42; DIGIT

Я ответил на твой вопрос?
Аноним 04/06/16 Суб 11:11:37  761115
>>761111
Ебучая макаба, &#42; = звезда.
Аноним 04/06/16 Суб 13:19:41  761172
>>760464 (OP)
Можно ещё перевести леволинейную грамматику в праволинейную грамматику через диаграмму состояний, тогда ты избавишься от левой рекурсии вообще.
Аноним 04/06/16 Суб 20:15:04  761560
>>761111
Я то же самое и написал.

И что ты предлагаешь с семантическими действиями делать? А, хотя я понял, это уже определяется реализацией. Надо подумать будет.

>>761172
По-подробней?
Аноним 05/06/16 Вск 00:00:06  761795
>>761560
>Я то же самое и написал.
Ни одной эпсилон-продукции у тебя не заметил.

>И что ты предлагаешь с семантическими действиями делать?
У тебя так и не вышло объяснить суть проблемы, которая с ними возникает.
Аноним 05/06/16 Вск 02:05:59  761908
>>761795
> Ни одной эпсилон-продукции у тебя не заметил.
Я дополнительно избавился от эпсилон-продукций. Какие эпсилон-продукции в PEG, поехавший?

> У тебя так и не вышло объяснить суть проблемы, которая с ними возникает.
Я хочу, чтобы все семантические действия, указанные в правиле, выполнялись в одном и том же контексте и ровно в тот момент, когда парсер до них доходит по тексту.
Аноним 05/06/16 Вск 03:14:04  761918
GLR
Аноним 05/06/16 Вск 17:03:33  762344
>>761908
>Какие эпсилон-продукции в PEG, поехавший?
Самые что ни на есть обыкновенные, милорд.
>Using the PEG formalism, the terminals (parsing expressions that do not depend on other expressions) are:
>...
>eps (short for 'epsilon') is an expression matching 'the empty char': it always succeeds and does not consume anything.
Пруфлинк:
https://github.com/PhilippeSigaud/Pegged/wiki/PEG-Basics
Ты мало того что дурачок, так еще и дурачок агрессивный. Нехорошо это. Это ж у тебя, дауна, не получается с простейшими алгоритмами совладать, а еще других ботами да поехавшими кроешь. Стыдись!

>Я хочу, чтобы все семантические действия, указанные в правиле, выполнялись в одном и том же контексте и ровно в тот момент, когда парсер до них доходит по тексту.
Странное желание, с учетом того, что порядок правил в тексте никак не связан с порядком их применения. Зачем тебе тогда вообще нужен парсер? Напиши лексер и всего делов, порядок операторов в тексте - задача лексического анализатора, а не синтаксического. Кроме того, не вполне понятно, что в твоём случае входит в понятие "контекст".
Аноним 05/06/16 Вск 19:14:58  762496
>>762344
> Какие эпсилон-продукции в PEG, поехавший?
Знаешь, в теории ты и Анджелину Джоли трахаешь. В теории. А практика обычно прозаичнее. Как ты по правилам с эпсилон-продукциями построишь парсер, который не будет зависать? Нет, понятно, что построить можно, но это будет нетривиальный процесс.

> Странное желание, с учетом того, что порядок правил в тексте никак не связан с порядком их применения.
Что в этом странного? Хочу, например, логгировать парсинг каждого оператора сложения. Парсер распарсил "5+6" - отлоггировался. Потом отпарсил еще "...+1" - еще отлоггировался. Все просто же!

> Кроме того, не вполне понятно, что в твоём случае входит в понятие "контекст".
Область видимости переменных. Хочу, чтобы все переменные, которые объявляются в семантических действиях в пределах одного правила, находились в одной области видимости. А переменные другого правила - в другой, отдельной.
Аноним 05/06/16 Вск 20:16:25  762562
>>762496
>понятно, что построить можно, но это будет нетривиальный процесс.
Нетривиальность зависит от того, кто строит. Для тебя, к примеру, и без эпсилон-продукций процесс явно нетривиален. Кроме того, прекращай вертеть жопой, маня - только что ты говорил, цитирую:
>Какие эпсилон-продукции в PEG, поехавший?
Ты не говорил о проблемах реализации таких грамматик, ты утверждал именно факт отсутствия эпсилон-продукций в PEG, так что не визжи теперь про Джоли, противно слушать.

>Хочу, например, логгировать парсинг каждого оператора сложения.
Вот одна только эта фраза уже многое говорит о содержимом твоей головы - там хаос. Какой, в частности, смысл ты вкладываешь в словосочетание "парсинг оператора сложения"? Навскидку это может быть:

Считывание терминала "+" из входящего потока токенов.
Предварительное обнаружение соответствия токенов из входящего потока некоему правилу грамматики, которое ты условно обозначил как "оператор сложения" (для парсеров с возвратом - окончательное обнаружение в них можно будет констатировать только по окончании работы).
Окончательное обнаружение вышеупомянутого соответствия (для LL-парсеров).

Так что же из вышеперечисленного в твоём понимании "парсер что-то распарсил", говна ты кусок?

>Хочу, чтобы все переменные, которые объявляются в семантических действиях в пределах одного правила, находились в одной области видимости. А переменные другого правила - в другой, отдельной.
А какого хуя ты там
вообще* определяешь какие-то переменные? Что вообще у тебя представляет собой "семантическое правило"? Какая проблема лепить любые данные к узлу в дереве разбора и там с ними работать как угодно в ололо-контексте этого самого узла? Ты говорить-то научись уже, маня, а то всё из тебя приходится клещами вытягивать.
Аноним 06/06/16 Пнд 02:10:24  762744
>>762562
Ты из этих, из компуктер-сцайентистов-обосцайентистов, что ли? Зачем ты пишешь такие простыни для объяснения очевидных вещей?

Неужели не понятно, что меня только проблема реализации и интересует?

Какой, в частности, смысл ты вкладываешь в словосочетание "парсинг оператора сложения"?

Смотри, есть правила:

expr <-
expr "+" expr /
expr "." expr /
number ;

Дополним семантическими действиями:

expr <-
expr { print("Пробуем сложение") } "+" expr { print("Распарсили сложение!") } /
expr { print("Пробуем умножение") } "." expr { print("Распарсили умножение!") } /
number ;

На вот таком тексте:

5+10.1

оно должно выдать:

Пробуем сложение
Пробуем сложение
Пробуем умножение
Распарсили умножение!
Распарсили сложение!

Так понятнее?

> А какого хуя ты там вообще определяешь какие-то переменные?
Хочу и определяю. Porblems, officer?

Хочу вот так писать:

expr <-
expr { n:=1 } "+" expr { print(n) } /
expr { n:=2 } "." expr { print(n) } /
number ;

> Какая проблема лепить любые данные к узлу в дереве разбора
Такая, что у меня не строится дерево разбора. По крайней мере, оно не хранится в памяти. Действия при разборе целиком определяются вставками { ... }.
Аноним 06/06/16 Пнд 02:49:37  762748
>>762744
>Неужели не понятно, что меня только проблема реализации и интересует?
О том, что тебя интересует, речи не шло. Цитировать не буду, заебало уже. Чем быстрее ты отучишься разговаривать с полным ртом говна, тем быстрее окружающие начнут тебя понимать.

>у меня не строится дерево разбора.
Ну и кто из нас поехавший? Так построй, или тебе мамка запрещает деревья разбора строить?

Даже если построишь - ты чисто физически не сможешь задавать разные семантические значения одному и тому же нетерминалу. Тебе придется вводить в своей грамматике дополнительные промежуточные нетерминалы для каждого из своих семантических значений.
Аноним 06/06/16 Пнд 11:42:51  762812
>>762748
> Так построй, или тебе мамка запрещает деревья разбора строить?
Про ограниченность памяти слышал, не? Я не могу с тобой больше разговаривать, ты очень тупой.

> Даже если построишь - ты чисто физически не сможешь задавать разные семантические значения одному и тому же нетерминалу.
expr <- e1:expr "+" e2:expr { return new Add(e1, e2); } /
e1:expr "." e2:expr { return new Mul(e1, e2); } /
n:number { return new Number(n); }

1+5*10

Add[Number["1"], Mul[Number["5"], Number["10"]]]
Аноним 06/06/16 Пнд 22:29:03  763234
>>762812
>Про ограниченность памяти слышал, не?

От тебя - нет, не слышал. От тебя вообще хуй чего услышишь про твою задачу, одно нытьё и надувание щёк.

>Я не могу с тобой больше разговаривать, ты очень тупой.
Ну сиди тогда ЛОГИРУЙ свои грамматики один, лол. У тебя же отлично получается.
Аноним 06/06/16 Пнд 23:54:46  763287
14652464870210.png (66Кб, 421x138)
>>763234

[Назад][Обновить тред][Вверх][Каталог] [Реквест разбана] [Подписаться на тред] [ ] 28 | 3 | 10
Назад Вверх Каталог Обновить

Топ тредов