1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/fawdlstty-Facc

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
chapter_4.md 5.7 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 30.11.2024 13:48 224b242

Глава 4: лучшие практики Facc

Левая рекурсия

Facc позволяет использовать выражения с левой рекурсией по своему усмотрению.

Приоритет

Приоритет необходимо обрабатывать самостоятельно. Например, следующие четыре операции:

op2_expr ::= expr (op2_sign expr)+

Вышеупомянутое op2_expr может соответствовать:

  • expr op2_sign expr
  • expr op2_sign expr op2_sign expr
  • expr op2_sign expr op2_sign expr op2_sign expr
  • expr op2_sign expr op2_sign expr op2_sign expr op2_sign expr
  • ...

Используя этот метод, вычисления одного уровня в AST-дереве перечисляются параллельно, а затем вручную определяется способ вычисления на основе приоритета символов.

Метод расширения

Например, для идентификации идентификатора требуется буквенно-цифровой символ и китайский иероглиф, и он не должен начинаться с цифры. По умолчанию он делится на две части:

id ::= [a-zA-Z\u0100-\uffff_] [0-9a-zA-Z\u0100-\uffff_]*

С помощью метода PrintTree можно увидеть, что первый символ и последующие символы разделены, образуя две части, что создаёт неудобства при использовании ID. Здесь можно добавить метод расширения:

static class AstExtensionMethods {
    public static string Value (this IdAST _a) => $"{_a.Value_0}{_a.Value_1}";
}

При последующем ручном анализе AST можно получить строку идентификатора через id.Value (). Другие структуры AST также могут выполнять аналогичные операции, упрощая анализ и обработку AST.

Создание пользовательского кода

Facc предоставляет альтернативный способ расширения методов, используя пользовательский код генерации. Эта функция позволяет разработчикам встраивать строковый код в методы AST.

Способ использования (сначала обратите внимание на пример кода):

_generator.Generate (null);

Здесь есть параметр, который мы просто передаём как null. Теперь замените его объектом словаря, где ключ означает имя класса, а значение — добавляемый строковый код. Просто сопоставьте класс и код, который нужно добавить, чтобы эта функция вставила соответствующий код в анализатор AST. Пример:

var _ext_code = new Dictionary<string, string> {
    ["ExprAST"] = "public int UserData = 0;",
};
_generator.Generate (_ext_code);

Сравнение преимуществ и недостатков метода расширения и этого метода:

  • Преимущества:
    • Возможность встраивания пользовательских переменных, геттеров/сеттеров, пользовательских статических методов.
    • Изменение анализатора проще, чем метод расширения. Если ошибка в коде приводит к сбою генерации анализатора, все методы расширения должны быть закомментированы для повторной компиляции.
  • Недостатки:
    • Можно использовать только в виде строки, невозможно проверить во время компиляции AST.
      • Решение: после создания AST напишите код внутри него, а затем скопируйте строку в пользовательский код создания.

Разработчики могут быть удивлены тем, что для встраивания кода необходимо передать имя класса, а не идентификатор grammar. Причина такого дизайна заключается в том, что если существует вложенная структура, такая как:

op2_expr ::= expr (op2_sign expr)+

Тогда будут созданы два класса: Op2ExprAST и Op2ExprAST_1, последний используется для описания синтаксической структуры op2_sign expr. Указание имени класса позволяет правильно различать уровни вложенности grammar.

Регулировка приоритета

В проекте Facc.Example приоритет распознаётся и настраивается вручную с использованием пользовательского кода генерации. Для получения дополнительной информации обратитесь к примеру.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/fawdlstty-Facc.git
git@api.gitlife.ru:oschina-mirror/fawdlstty-Facc.git
oschina-mirror
fawdlstty-Facc
fawdlstty-Facc
main