[parser]
От: WolfHound  
Дата: 19.01.12 12:39
Оценка: 164 (3)
Сделал генерацию АСТ.
https://github.com/rampelstinskin/ParserGenerator/commit/fec7a7645f09db45c20eda7fa0f50f1feab4d0f1
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: [parser]
От: Аноним  
Дата: 19.01.12 12:42
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Сделал генерацию АСТ.


можно подробнее?
Re[2]: [parser]
От: Ziaw Россия  
Дата: 19.01.12 13:48
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, WolfHound, Вы писали:


WH>>Сделал генерацию АСТ.


А>можно подробнее?


Насколько я понял, методы парсера, создающие аст, теперь можно описывать декларативно прямо в грамматике. Выглядит удобно.
Re[2]: [parser]
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.01.12 18:38
Оценка:
Здравствуйте, Аноним, Вы писали:

WH>>Сделал генерацию АСТ.


А>можно подробнее?

https://github.com/rampelstinskin/ParserGenerator/blob/master/Test/Main.n
abstract class ExprAst : Located { } // Базовый класс для AST

[ParserGrammar(Options = EmitDebugSources,
  grammar
  {
    using IncParser;
    using NumParser;

    any = ['\u0000'..'\uFFFF'];
    s : void = ' '*;

    [StartRule]
    start : ExprAst = s expr !any;

    [StartRule]
    expr : ExprAst; // расширяемое правило возвращающее базовый класс определенный выше

    // расширяющее правило задает ветку AST с полями: 
    // l : NToken; expr : ExprAst; r :NToken; - типы полей выводятся из типов правил
    [Ast(l, expr, r)] rounds is expr = '('s expr ')'s; 

    [Ast(num)]        num is expr = number s;

    [Ast(op, expr)]   neg is expr = '-'s expr : 100;
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
http://nemerle.org/Banners/?g=dark
Re[3]: [parser]
От: IT Россия linq2db.com
Дата: 19.01.12 19:30
Оценка:
Здравствуйте, VladD2, Вы писали:

А>>можно подробнее?

VD>https://github.com/rampelstinskin/ParserGenerator/blob/master/Test/Main.n

А все эти 's' нельзя как-то убрать, чтобы постоянно о них не думать?
//rsdn.org/forum/images/bis.gif Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: [parser]
От: Ka3a4oK  
Дата: 19.01.12 19:50
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, VladD2, Вы писали:


А>>>можно подробнее?

VD>>https://github.com/rampelstinskin/ParserGenerator/blob/master/Test/Main.n

IT>А все эти 's' нельзя как-то убрать, чтобы постоянно о них не думать?


Можно сделать для грамматики(для парсера?) опцию — ПробелыМеждуАйтемами=true/false.
... << RSDN@Home 1.2.0 alpha 5 rev. 1537>>
Re[4]: [parser]
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.01.12 22:43
Оценка:
Здравствуйте, IT, Вы писали:

IT>А все эти 's' нельзя как-то убрать, чтобы постоянно о них не думать?


Убрать можно. Но постоянно думать о них придется .
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
http://nemerle.org/Banners/?g=dark
Re[5]: [parser]
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.01.12 22:49
Оценка:
Здравствуйте, Ka3a4oK, Вы писали:

KK>Можно сделать для грамматики(для парсера?) опцию — ПробелыМеждуАйтемами=true/false.


"пробелы" (а точнее пробельное void-правило) надо ставить только после "токенов", т.е. правил которые не преобразуются в АСТ или не имеют обработчиков.

А опция нужна не для всех грамматики, а для отдельных правил. Точнее можно сделать глобальную настройку поведения по умолчанию и возможность переключения ее для отдельных правил с помощью атрибутов.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
http://nemerle.org/Banners/?g=dark
Re[6]: [parser]
От: hardcase Пират http://nemerle.org
Дата: 20.01.12 10:53
Оценка: +1 -1
Здравствуйте, VladD2, Вы писали:

VD>А опция нужна не для всех грамматики, а для отдельных правил. Точнее можно сделать глобальную настройку поведения по умолчанию и возможность переключения ее для отдельных правил с помощью атрибутов.


Насчет глобальной настройки не уверен. Мне видится полезным другой сценарий: при обнаружении использования в правиле обращений к s считать что автор расставил их по делу и автоматику отключать. В противном случае расставлять s автоматически. Атрибут для правила нужен для отключения автоматической расстановки s.
http://nemerle.org/Banners/?t=Developer!&g=dark /* иЗвиНите зА неРовнЫй поЧерК */
Re[3]: [parser]
От: Аноним  
Дата: 20.01.12 15:58
Оценка:
Здравствуйте, VladD2, Вы писали:

[Ast(l, op, r)] div is expr = expr : 20 '/'s expr : 20;


| CalcParser.Expr.Div(l, _, r) => $"[ $(printAst(l)) / $(printAst(r)) ]"


Зачем тут '/' в op если не используется в разборе?
Вариант объявляется автоматом?
Re[4]: [parser]
От: Аноним  
Дата: 20.01.12 16:32
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, VladD2, Вы писали:


Можно изменить синтаксис на

[Ast(l,  r)]   div is expr = expr : 20 !'/'s expr : 20;


где восклицательный знак означает что параметр не используется....
Re[5]: [parser]
От: hardcase Пират http://nemerle.org
Дата: 20.01.12 17:36
Оценка:
Здравствуйте, Аноним, Вы писали:

А>где восклицательный знак означает что параметр не используется....


! и & используются для предикатных правил.
http://nemerle.org/Banners/?t=Developer!&g=dark /* иЗвиНите зА неРовнЫй поЧерК */
Re[7]: [parser]
От: VoidEx  
Дата: 20.01.12 19:17
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Насчет глобальной настройки не уверен. Мне видится полезным другой сценарий: при обнаружении использования в правиле обращений к s считать что автор расставил их по делу и автоматику отключать. В противном случае расставлять s автоматически. Атрибут для правила нужен для отключения автоматической расстановки s.


Впихнули где-нибудь s и семантика поменялась. Почему так любят неявность, граничащую с неочевидностью? Обломается что ли человек будущим поколениям читателей кода пометку оставить? А тем потом и рассматривать код на наличие этих самых s не придётся.
Или подразумевается, что IDE и так будет выдавать такую инфу?
Re[8]: [parser]
От: catbert  
Дата: 20.01.12 19:29
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Впихнули где-нибудь s и семантика поменялась. Почему так любят неявность, граничащую с неочевидностью?


Вот не знаю почему, но Ада и Алгол как-то не прижились в программистcкой среде.
http://nemerle.org/banners/?t=%20catbert%20
Re[4]: [parser]
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.01.12 22:37
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Зачем тут '/' в op если не используется в разборе?


В реальных парсерах лишней информации не бывает. В op будет помещена информация о "токене" (NToken), т.е. строке исходного файла которая сопоставилась с данным правилом. Такая информация может быть нужна при рефакторинге или для вычисления правильного сообщения об ошибке.

А>Вариант объявляется автоматом?


Да. Создается по вариантному типу на каждое сочетание парсера и расширяемого правила. Таким образом каждый парсер расширяющий некоторое правило из другого парсера вводит новый вариант в котором описаны вхождения для каждого расширения.

В примере калькулятора для правила expr генерируется два вариантных типа:
* CalcParser.Expr
* IncParser.Expr

Их использование можно видеть в примере ниже:
https://github.com/rampelstinskin/ParserGenerator/blob/master/Test/Main.n#L82
          def printAst(ast : ExprAst)
          {
            match (ast)
            {
              | CalcParser.Expr.Rounds(_, ast, _) => $"( $(printAst(ast)) )"
              | CalcParser.Expr.Num(num)          => $"$num"
              | CalcParser.Expr.Neg(_, v)         => $"[ - $(printAst(v)) ]"
              | CalcParser.Expr.PrefixDec(_, v)   => $"[ -- $(printAst(v)) ]"
              | CalcParser.Expr.PostfixDec(v, _)  => $"[ $(printAst(v)) -- ]"
              | CalcParser.Expr.Add(l, _, r)      => $"[ $(printAst(l)) + $(printAst(r)) ]"
              | CalcParser.Expr.Sub(l, _, r)      => $"[ $(printAst(l)) - $(printAst(r)) ]"
              | CalcParser.Expr.Mul(l, _, r)      => $"[ $(printAst(l)) * $(printAst(r)) ]"
              | CalcParser.Expr.Div(l, _, r)      => $"[ $(printAst(l)) / $(printAst(r)) ]"
              | CalcParser.Expr.Mod(l, _, r)      => $"[ $(printAst(l)) % $(printAst(r)) ]"
              | CalcParser.Expr.Pow(l, _, r)      => $"[ $(printAst(l)) ^ $(printAst(r)) ]"

              | IncParser.Expr.Plus(_, v)         => $"[ + $(printAst(v)) ]"
              | IncParser.Expr.PrefixInc(_, v)    => $"[ ++ $(printAst(v)) ]"
              | IncParser.Expr.PostfixInc(v, _)   => $"[ $(printAst(v)) ++ ]"
            }
          }


Оба вариантных типа наследуются от единого базового класса (в данном случае ExprAst) который задается явно и определяется вручную. Полезно наследовать такой класс от Located. Тогда будет автоматически поддерживаться установка местоположения элементов AST.

Для каждого правила расширяющего другое правило вводится по одному вхождению варианта с тем же именем (но с большой буквы).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
http://nemerle.org/Banners/?g=dark
Re[8]: [parser]
От: hardcase Пират http://nemerle.org
Дата: 21.01.12 07:59
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Впихнули где-нибудь s и семантика поменялась.


Поменяется семантика правила в котором воткнули s.
http://nemerle.org/Banners/?t=Developer!&g=dark /* иЗвиНите зА неРовнЫй поЧерК */
Re[9]: [parser]
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.01.12 13:15
Оценка:
Здравствуйте, hardcase, Вы писали:

VE>>Впихнули где-нибудь s и семантика поменялась.


H>Поменяется семантика правила в котором воткнули s.


Боюсь будет много ошибок по случайности.

В "лексерных" правилах, вроде описания чисел, пробельные символы, обычно, нужны только вконце правила. Но стоит забыть поставить s и мы получим ошибочную грамматику. При этом с первого взгляда это не будет понятно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
http://nemerle.org/Banners/?g=dark
Re: [parser]
От: Аноним  
Дата: 24.01.12 07:18
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Сделал генерацию АСТ.

WH>https://github.com/rampelstinskin/ParserGenerator/commit/fec7a7645f09db45c20eda7fa0f50f1feab4d0f1

скачал проект, там нет половины файлов...

например ExtensionRuleBase.n
Re: [parser]
От: Аноним  
Дата: 24.01.12 11:12
Оценка:
Здравствуйте, WolfHound, Вы писали:

Скачал, пигшет что не хватает файлов... их действительно нет в скаченом, но они используются...
где как взять
Re[2]: [parser]
От: _NN_ www.nemerleweb.com
Дата: 24.01.12 12:00
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, WolfHound, Вы писали:


WH>>Сделал генерацию АСТ.

WH>>https://github.com/rampelstinskin/ParserGenerator/commit/fec7a7645f09db45c20eda7fa0f50f1feab4d0f1

А>скачал проект, там нет половины файлов...


А>например ExtensionRuleBase.n


Есть в поставке Nemerle:
https://github.com/rsdn/nemerle/blob/master/snippets/peg-parser/Nemerle.Peg/ExtensionRuleBase.n
http://rsdn.nemerleweb.com
http://nemerleweb.com
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.