В переводчике, что (обычно) идет после лексера? - PullRequest
3 голосов
/ 15 мая 2011

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

  • Интерпретатор получает данные
  • Лексер / токенизатор получает данные и разграничивает токены
  • The x получает список токенов
  • ???
  • Код выполняется

Какой шаг (и) принадлежит в ???пятно, и что происходит вместо x (то есть, что получает и воздействует на токены, которые создал лексер)?

Ответы [ 3 ]

2 голосов
/ 15 мая 2011

Анализ выполняется, чтобы превратить поток токенов в структурированную, проверенную, синтаксическую информацию. Если вы хотите оценить, скажем, арифметическое выражение:

( x + 4 ) * 3

Вы не делаете это, сканируя токены слева направо. Вам нужно выяснить порядок операций. Вам необходимо превратить токены между ключевым словом if и фигурными скобками { } в высокоуровневую структуру, описывающую оператор if, чтобы вы могли оценить ее, не манипулируя кучей токенов. И вам нужно проверить синтаксис, который по сути невозможен без правильного его синтаксического анализа; пожалуйста, прочитайте о контекстно-свободных грамматиках .

Вышеприведенное выражение станет абстрактным синтаксическим деревом , как показано ниже:

    *
  +   3
 x y

Оценить это довольно просто - просто обойдите дерево и посмотрите вверх x и y в окружающей среде.

Аналогично, с учетом ряда утверждений, подобных этому:

if ( p && q ) { foo ; bar ; } else { baz ; }

абстрактное синтаксическое дерево может иметь следующую общую структуру:

IfStatement:
  Condition:
    LogicalConjunction:
      LeftOperand: p
      RightOperand: q
  TruePart:
    BasicBlock:
      Statement: foo
      Statement: bar
  FalsePart:
    BasicBlock:
      Statement: baz

Надеюсь, вы можете себе представить, как вы бы проходили это дерево, чтобы интерпретировать код.

Учебник по переводчикам, который я настоятельно рекомендую, - Основы языков программирования .

2 голосов
/ 18 июня 2011

Я начну с рекомендации классической и бесплатной книги: Структура и интерпретация компьютерных программ ( видео лекции )

Lisp является базовым интерпретатором, а все остальное в некотором роде является вариацией темы.

В общем случае следующие шаги:

  • Лексический анализ принимает поток символов и производит токены
  • Анализ разбирает токены (плоский список) и создает структуру данных, называемую абстрактным синтаксическим деревом (AST). Этот шаг может быть очень простым (Lisp) или удивительно сложным (C ++, Ruby).
  • Оценить АСТ. Детали немного отличаются, но это довольно глубокая прогулка по дереву. Листья - это data (числа, строки, константы, переменные). Узлы являются либо примитивными функциями (математика, обработка данных, управляющие структуры), либо составными функциями более высокого уровня. Каждый узел должен сводиться к чему-то, что может быть подано непосредственно в узел над ним.

Этот последний шаг равен «код выполняется». Для скомпилированного языка или языка Just-In-Time (JIT) последним шагом является перевод AST обратно в машинные инструкции. Также важно отметить два других шага, которые могут присутствовать. Одним из них является перевод на более простой язык, такой как c--, LLVM, .NET или Java bitecode. Другим является десагеринг и / или оптимизация, которая может происходить между анализатором и оценщиком. Например, Haskell несколько печально известен огромным количеством десагеринга.

В заключение я призываю вас попробовать один из многочисленных пошаговых руководств для написания интерпретатора Scheme (диалект Лиспа). Скорее всего, где-то в сети есть ваш любимый язык.

1 голос
/ 15 мая 2011

Для интерпретатора парсер обычно делает две вещи

  1. Генерация p-кода
  2. Добавить элементы в таблицу символов

После этого executor выполнит p-код и идентификаторы поиска и т. Д. В таблице символов.

Анализатор анализирует поток полученных им токенов и генерирует более простой и эффективный для выполнения p-code, в то же время вводятся любые символы, такие как переменные, функции, структуры сложных типов данных и т. Д., Обнаруженные на этапе синтаксического анализа таблица символов и ссылки в р-код.

Исполнитель затем обрабатывает поток p-кода и выполняет инструкции и использует таблицу символов для поиска любых идентификаторов, с которыми он сталкивается в таблице символов.

...