Pull to refresh

Интерпретатор PHP: а что там внутри… Lexer

Level of difficulty Hard
Reading time 3 min
Views 1.2K
Итак, ранее мы начали наш рассказ о Lexer языка PHP. Стоит обратить внимание на следующие его особенности:

  • Лексер — это компонент, который разбивает исходный код на токены. Это первый шаг в парсинге PHP-кода.
  • Лексер использует таблицы переходов (transition tables) для определения того, какой символ является следующим в потоке токенов.
  • Лексер работает в два этапа: первый этап — это сканирование, второй — это анализ.
  • На первом этапе лексер сканирует исходный код и разбивает его на токены. На этом этапе лексер выполняет проверку синтаксиса.
  • На втором этапе лексер анализирует токены, выявляя в них смысловые единицы (например, идентификаторы, числа, строки и т. д.).
  • Лексер может генерировать ошибки парсинга, если обнаруживает некорректный код.
  • PHP-лексер работает быстрее, если на вход подаются корректные данные. Если же на входе содержится некорректный код, то лексер может потребовать значительно больше времени на обработку.
  • Лексер в PHP использует двоичное дерево для хранения токенов. Это позволяет обращаться к токенам быстро и эффективно.


Сканирование является первым этапом работы лексера. Он заключается в процессе разбиения входного потока символов на отдельные лексемы, которые затем могут быть преобразованы в токены.

На вход лексеру подается входной поток символов, который может быть строкой или файлом. Лексер начинает считывать символы из потока и строит текущую лексему. Затем он проверяет, соответствует ли текущая лексема одному из заданных токенов. Если текущая лексема не соответствует ни одному из токенов, лексер добавляет символ к текущей лексеме и переходит к следующему символу в потоке. Если текущая лексема соответствует токену, лексер генерирует токен и переходит к следующему символу в потоке. Лексер повторяет этот процесс до тех пор, пока не достигнет конца потока символов.

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

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

Анализ (парсинг) — это второй этап работы компилятора, после лексического анализа. Он заключается в разборе последовательности токенов, которые были получены на предыдущем этапе, и создании из них абстрактного синтаксического дерева (AST).

AST представляет собой структуру данных, которая описывает логическую структуру программы. Это дерево состоит из узлов, которые представляют различные элементы программы, такие как операторы, выражения, функции и т.д. Каждый узел содержит информацию о своем типе и может иметь дочерние узлы.

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

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

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

AST (абстрактное синтаксическое дерево) — это структура данных, которая представляет собой дерево разбора программного кода на языке программирования. Каждый узел дерева соответствует конструкции языка программирования, такой как выражение, оператор, функция и т.д. Вот пример AST для простой программы на языке PHP:

Program
└─ Namespace (name: "MyNamespace")
├─ Class (name: "MyClass")
│ ├─ Method (name: "myMethod")
│ │ └─ Statement (type: "echo")
│ │ └─ StringLiteral (value: "Hello, world!")
│ └─ Property (name: "myProperty")
└─ Function (name: "myFunction")
└─ Statement (type: "return")
└─ IntegerLiteral (value: 42)


Этот AST представляет простую программу, которая содержит пространство имен, класс, метод, свойство и функцию. Каждый узел дерева соответствует конструкции языка программирования, которую можно анализировать и обрабатывать.
Tags:
Hubs:
+58
Comments 65
Comments Comments 65

Articles