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;
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Ka3a4oK, Вы писали:
KK>Можно сделать для грамматики(для парсера?) опцию — ПробелыМеждуАйтемами=true/false.
"пробелы" (а точнее пробельное void-правило) надо ставить только после "токенов", т.е. правил которые не преобразуются в АСТ или не имеют обработчиков.
А опция нужна не для всех грамматики, а для отдельных правил. Точнее можно сделать глобальную настройку поведения по умолчанию и возможность переключения ее для отдельных правил с помощью атрибутов.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>А опция нужна не для всех грамматики, а для отдельных правил. Точнее можно сделать глобальную настройку поведения по умолчанию и возможность переключения ее для отдельных правил с помощью атрибутов.
Насчет глобальной настройки не уверен. Мне видится полезным другой сценарий: при обнаружении использования в правиле обращений к s считать что автор расставил их по делу и автоматику отключать. В противном случае расставлять s автоматически. Атрибут для правила нужен для отключения автоматической расстановки s.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[3]: [parser]
От:
Аноним
Дата:
20.01.12 15:58
Оценка:
Здравствуйте, VladD2, Вы писали:
[Ast(l, op, r)] div is expr = expr : 20 '/'s expr : 20;
Здравствуйте, hardcase, Вы писали:
H>Насчет глобальной настройки не уверен. Мне видится полезным другой сценарий: при обнаружении использования в правиле обращений к s считать что автор расставил их по делу и автоматику отключать. В противном случае расставлять s автоматически. Атрибут для правила нужен для отключения автоматической расстановки s.
Впихнули где-нибудь s и семантика поменялась. Почему так любят неявность, граничащую с неочевидностью? Обломается что ли человек будущим поколениям читателей кода пометку оставить? А тем потом и рассматривать код на наличие этих самых s не придётся.
Или подразумевается, что IDE и так будет выдавать такую инфу?
Здравствуйте, Аноним, Вы писали:
А>Зачем тут '/' в op если не используется в разборе?
В реальных парсерах лишней информации не бывает. В op будет помещена информация о "токене" (NToken), т.е. строке исходного файла которая сопоставилась с данным правилом. Такая информация может быть нужна при рефакторинге или для вычисления правильного сообщения об ошибке.
А>Вариант объявляется автоматом?
Да. Создается по вариантному типу на каждое сочетание парсера и расширяемого правила. Таким образом каждый парсер расширяющий некоторое правило из другого парсера вводит новый вариант в котором описаны вхождения для каждого расширения.
В примере калькулятора для правила expr генерируется два вариантных типа:
* CalcParser.Expr
* IncParser.Expr
Оба вариантных типа наследуются от единого базового класса (в данном случае ExprAst) который задается явно и определяется вручную. Полезно наследовать такой класс от Located. Тогда будет автоматически поддерживаться установка местоположения элементов AST.
Для каждого правила расширяющего другое правило вводится по одному вхождению варианта с тем же именем (но с большой буквы).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, hardcase, Вы писали:
VE>>Впихнули где-нибудь s и семантика поменялась.
H>Поменяется семантика правила в котором воткнули s.
Боюсь будет много ошибок по случайности.
В "лексерных" правилах, вроде описания чисел, пробельные символы, обычно, нужны только вконце правила. Но стоит забыть поставить s и мы получим ошибочную грамматику. При этом с первого взгляда это не будет понятно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.