Как написать простой Logo-like интерпретатор в C #? - PullRequest
0 голосов
/ 12 января 2012

Как мне написать переводчика на C # и как он работает?

Также любая другая информация о нормальных интерпретаторах - то есть (Python) и о том, как она читает, если операторы, вычисления выражений и т. Д. Работают - или даже псевдокод, будет очень цениться.

1 Ответ

1 голос
/ 12 января 2012

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

Первый токенизация, составьте список всех компонентов кода, строки, ключевых слов, операторов и т. Д. Каждый занимает один слот, например:

  1. печать
  2. (
  3. "Hello \" world \ ""
  4. )

Это не должно быть слишком сложно.

Теперь проведите классификацию идентификаторов, в зависимости от их положения в коде и т. Д., Вы сможете определить, являются ли они вызовами функций, операторами, переменными или чем-то еще.

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

Ваш список должен быть превращен в дерево, теперь вы можете начинать блокировать вещи, каждая пара скобок образует блок, и в зависимости от языка другие конструкции могут составлять блок в виде скобок. (операторы начала и конца и тому подобное можно просто рассматривать как скобки). Такой блок вы просто превращаете в один элемент списка, содержащий список всех его подэлементов. Здесь и далее вы обходите дерево один раз для каждого уровня приоритета оператора и выполняете блокировку для этих операторов.

Теперь вы можете создавать списки всех переменных и функций, по одному для каждой области, и проверять отсутствие коллизий.

Для каждой области вы создаете упорядоченный список переменных, чтобы вы могли построить блок памяти и точно знать, куда каждая из них идет.

Заменить имена переменных и функций ссылками на расположение блоков памяти и объявления функций соответственно.

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

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

Обычные языковые конструкции должны быть довольно просты в обращении, когда есть if, вы знаете, что за ним следуют два блока, если первый блок оценивается как ложный, пропустите второй. Аналогично, циклы и другие конструкции обрабатываются тривиально, если вы рассматриваете их как состоящие из фиксированного числа блоков с некоторыми тривиальными правилами, определяющими, когда выполнять каждый из них.


Я сейчас дал вам структурированный подход, умение его реализовать я не могу гарантировать. Существует бесчисленное множество возможных изменений производительности, и многое из того, что я не сказал явно, как реализовать, вам придется понять.

...