Переводчики: обработка включает / импортирует - PullRequest
2 голосов
/ 09 апреля 2010

Я построил интерпретатор в C ++, и до сих пор все отлично работает, но теперь я застрял с дизайном импорта / включения /, однако вы хотите вызвать его функцией.

Я думал о следующем:

  • Обработка включает в процесс токенизации: когда в коде обнаружен include, функция токенизации рекурсивно вызывается с указанным именем файла Затем токенизированный код файла include d добавляется в предыдущую позицию включения. Недостатки: без условного включения (!)

  • Обработка включает в себя в процессе перевода: я не знаю как. Все, что я знаю, это то, что PHP must делает это так, как возможны условные включения.

Теперь мои вопросы:

  • Что мне делать с включениями?
  • Как современные интерпретаторы (Python / Ruby) справляются с этим? Разрешают ли они условные включения?

1 Ответ

3 голосов
/ 10 апреля 2010

Эту проблему легко решить, если у вас чистый дизайн и вы знаете, что делаете. Иначе это может быть очень сложно. Я написал по крайней мере 6 переводчиков, которые все имеют эту функцию, и это довольно просто.

  1. Ваш интерпретатор должен поддерживать среду , которая знает обо всех глобальных переменных, функциях, типах и т. Д., Которые были определены. Возможно, вам будет удобнее называть это «таблицей символов».

  2. Вам необходимо определить внутреннюю функцию, которая читает файл и обновляет среду. В зависимости от вашей языковой структуры, вы можете или не можете делать некоторую оценку в тот момент, когда вы читаете что-то. Мои переводчики очень динамичны и оценивают каждое определение, как только оно прочитано.

  3. Ваша жизнь будет бесконечно легче, если вы структурируете своего переводчика по слоям:

    • Tokenizer (разбивает ввод на токены)
    • Parser (читает по одному токену за раз, преобразует в дерево абстрактного синтаксиса)
    • Evaluator (читает абстрактный синтаксис и обновляет среду)

Абстрактно-синтаксическое дерево действительно является ключом. Если у вас есть это, когда вы сталкиваетесь с конструкцией import / include на входе, вы просто делаете рекурсивный вызов и получаете более абстрактный синтаксис. Вы можете сделать это в анализаторе или оценщике. Если вам нужен условный импорт, вы должны сделать это в оценщике, поскольку только оценщик может вычислить условие.

Исходный код для моих переводчиков находится в сети. Два из них написаны на С; остальные написаны в стандарте ML.

...