Создание собственного компилятора C# с помощью ANTLR: Единица компиляции

Ответы варьируются между языками. Например, в Java класс может реализовать (наследуйтесь), несколько интерфейсов, но только наследовались одному абстрактному классу. Таким образом, интерфейсы дают Вам больше гибкости. Но это не верно в C++.

9
задан halfer 9 December 2018 в 22:51
поделиться

3 ответа

Я никогда не работал с ANTLR из C #, но, следуя вашей ссылке на API, BaseTree явно не интерфейс - это класс , и он имеет общедоступные свойства: Введите , чтобы получить тип узла, Текст , чтобы получить (я предполагаю) исходный текст, соответствующий ему, и Дети , чтобы получить дочерние узлы. Что еще нужно, чтобы пройтись по нему?

3
ответ дан 4 December 2019 в 23:07
поделиться

Если бы я собирался сегодня сделать компилятор C #, вот что я бы сделал в качестве первой попытки:

  1. Начните с цели ANTLR C # 3 (из Конечно, я здесь предвзято - серьезно, вы можете использовать цель CSharp2 или CSharp3).
  2. Получите Visual Studio 2010 с .NET Framework 4. Ключевым моментом здесь является .NET 4 и его новые милые деревья выражений.
  3. Создайте базовый комбинированный парсер. Поместите в синтаксический анализатор как можно меньше логики. Он должен иметь несколько действий (если они есть), а на выходе должен быть AST без декорирования, по которому можно пройти с помощью LL (1) walker.
  4. Постройте грамматику дерева, чтобы пройти по дереву и идентифицировать все объявленные типы. Следует также сохранить поддеревья member_declaration для дальнейшего использования.
  5. Создайте обходчик по дереву, который проходит по единственному member_declaration и добавляет его в TypeBuilder . Следите за телами методов, но пока не углубляйтесь в них.
  6. Создайте обходчика по дереву, который будет обходить тело метода. Создайте Expression , соответствующее методу, и используйте метод CompileToMethod мой собственный API (см. Комментарии Павла и мои) для генерации кода IL.

Если вы выполняете действия в этом порядке, то, когда вы, наконец, анализируете выражения (тела методов, инициализаторы полей), вы можете использовать строку параметризованные методы , подобные этому , в Класс Expression для сохранения элементов разрешения работы.

  • Создайте обходчика по дереву, который проходит тело метода. Создайте Expression , соответствующее методу, и используйте метод CompileToMethod мой собственный API (см. Комментарии Павла и мои) для генерации кода IL.
  • Если вы выполняете действия в этом порядке, то, когда вы, наконец, анализируете выражения (тела методов, инициализаторы полей), вы можете использовать строку параметризованные методы , подобные этому , в Класс Expression для сохранения элементов разрешения работы.

  • Создайте обходчика по дереву, который проходит тело метода. Создайте Expression , соответствующее методу, и используйте метод CompileToMethod мой собственный API (см. Комментарии Павла и мои) для генерации кода IL.
  • Если вы выполняете действия в этом порядке, то, когда вы, наконец, анализируете выражения (тела методов, инициализаторы полей), вы можете использовать строку параметризованные методы , подобные этому , в Класс Expression для сохранения элементов разрешения работы.

    -2
    ответ дан 4 December 2019 в 23:07
    поделиться

    Тип дерева AST можно установить в параметрах грамматики на странице вверху файла примерно так:

    tree grammar CSharpTree;
    options { 
        ASTLabelType = CommonTree
    }
    

    Я бы построил третью грамматику или включил ее в существующую грамматику парсера, которая превращает дерево в классы, которые вы создаете. Например, предположим, что у вас есть правило, которое соответствует оператору «плюс» и имеет 2 аргумента. Вы можете определить правило, соответствующее этому дереву, которое создает класс, который вы написали, назовем его PlusExpression следующим образом:

    plusExpr returns [PlusExpression value]
       : ^(PLUS left=expr right=expr) { $value = new PlusExpression($left.value, $right.value); }
    

    expr будет другим правилом в ваших выражениях соответствия грамматики. left и right - это просто псевдонимы, присвоенные значениям дерева. Часть между {} в значительной степени преобразована в код C # дословно, за исключением замены ссылок на переменные. Файл.

    6
    ответ дан 4 December 2019 в 23:07
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: