Краткий ответ : разбор не подмножество компиляции.
Длинный ответ : обычно есть 3 шага для преобразования источника в другой формат:
- Лексирование, которое преобразует некоторую форму ввода в поток токенов.
- Синтаксический анализ, который преобразует поток токенов в абстрактное синтаксическое дерево (AST).
- Компиляция, которая преобразует AST в набор исполняемых инструкций (нативный код, байт-код и т. Д.).
(Для очень простых языков вам может даже не понадобиться парсер, вы можете напрямую скомпилировать поток токенов или ваш парсер может напрямую выводить нативный код.)
Итак, начните с необработанной строки, например:
let x = 0
while x < 10
print x
x := x + 1
Лексер собирается преобразовать его в поток токенов, возможно, что-то вроде этого:
[LET; String("x"); EQ; Int(0); NEWLINE; WHILE; String("x");
LT; VAL(10); ... ]
Анализатор преобразует поток в более значимую структуру данных, ваше абстрактное синтаксическое дерево:
// AST definition
type expr =
| Block of expr list
| Assign of string * expr
| While of expr * expr
| Call of string * expr list
| Add of expr * expr
| Var of string
| Int of int
// AST instance created from token stream
Block
[
Assign("x", Int(10));
While
(
LessThan(Var("x"), Int(10)),
Block
[
Call("print", [Var("x")]);
Assign("x", Add(Var("x"), Int(1)));
]
);
]
Получив AST, вы можете делать с ним все, что захотите:
- Вы конвертируете AST в собственный код (компиляция).
- или вы можете интерпретировать AST на лету, что вы можете сделать с помощью динамического языка программирования или движка шаблонов.
- или вы можете выполнить итерацию AST, чтобы сделать подсветку синтаксиса.
- или вы можете пройти AST и вывести эквивалентный код на другом языке.
- или вы можете найти все экземпляры
Var("x")
и заменить их на Var("y")
, аналогично инструменту рефакторинга кода).
Итак, хотя вы обычно анализируете ввод перед компиляцией, это не то же самое, что сказать, что синтаксический анализ является подмножеством компиляции.