Эту проблему легко решить, если у вас чистый дизайн и вы знаете, что делаете. Иначе это может быть очень сложно. Я написал по крайней мере 6 переводчиков, которые все имеют эту функцию, и это довольно просто.
Ваш интерпретатор должен поддерживать среду , которая знает обо всех глобальных переменных, функциях, типах и т. Д., Которые были определены. Возможно, вам будет удобнее называть это «таблицей символов».
Вам необходимо определить внутреннюю функцию, которая читает файл и обновляет среду. В зависимости от вашей языковой структуры, вы можете или не можете делать некоторую оценку в тот момент, когда вы читаете что-то. Мои переводчики очень динамичны и оценивают каждое определение, как только оно прочитано.
Ваша жизнь будет бесконечно легче, если вы структурируете своего переводчика по слоям:
- Tokenizer (разбивает ввод на токены)
- Parser (читает по одному токену за раз, преобразует в дерево абстрактного синтаксиса)
- Evaluator (читает абстрактный синтаксис и обновляет среду)
Абстрактно-синтаксическое дерево действительно является ключом. Если у вас есть это, когда вы сталкиваетесь с конструкцией import / include на входе, вы просто делаете рекурсивный вызов и получаете более абстрактный синтаксис. Вы можете сделать это в анализаторе или оценщике. Если вам нужен условный импорт, вы должны сделать это в оценщике, поскольку только оценщик может вычислить условие.
Исходный код для моих переводчиков находится в сети. Два из них написаны на С; остальные написаны в стандарте ML.