Является ли "разбор" подмножеством "компиляции"? - PullRequest
6 голосов
/ 30 ноября 2010

Когда я думаю о «компиляции», я думаю о превращении кода C ++ в двоичный файл.Или, возможно, C # в байт-код CLR.Но «синтаксический анализ» может быть чем-то вроде синтаксического анализа Python или языка веб-шаблонов, где ему не нужно создавать какие-либо двоичные файлы, но он может либо выполнить код немедленно, оператор за оператором, либо напрямую вывести HTML.

Будете ли вы выполнять одну и ту же задачу в любом случае?Игнорируя синтаксис языка, будет ли компиляция C ++ такой же сложной, как анализ файла шаблона сайта (Django, Smarty и т. Д.) Или Python?изучите "компиляцию" или прочитайте книгу по "компиляции". Обязательно ли я приобрету навыки разбора некомпилированных языков?

Ответы [ 4 ]

25 голосов
/ 01 декабря 2010

Краткий ответ : разбор не подмножество компиляции.

Длинный ответ : обычно есть 3 шага для преобразования источника в другой формат:

  1. Лексирование, которое преобразует некоторую форму ввода в поток токенов.
  2. Синтаксический анализ, который преобразует поток токенов в абстрактное синтаксическое дерево (AST).
  3. Компиляция, которая преобразует 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"), аналогично инструменту рефакторинга кода).

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

5 голосов
/ 30 ноября 2010

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

  • Парсер может вообще не генерировать какой-либо код.Это может быть разбор некоторого объекта данных (JSON, XML и т. Д.)
  • Компилятор может не иметь исходного кода для начала - он может быть представлен с абстрактным синтаксическим деревом, уже проанализированным, и просто должен выдатьсоответствующий код

Большинство компиляторов включают шаг синтаксического анализа, но я не думаю, что это обязательно "подмножество" компиляции, и синтаксический анализ, конечно же, не должен иметь ничего дляделать с компиляцией.

2 голосов
/ 01 декабря 2010

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

Однако вы обнаружите, что большая часть компиляции (разрешение имен, вывод типов, сопоставление с образцом, компиляция инструкций [pcode, а не машинный код], высокопроизводительное выполнение, оптимизация для особых случаев)полезен в обработке некомпилированных языков.Поэтому, если вы намереваетесь сделать больше, чем просто буквально parse , вы все равно захотите изучить технологию компиляции.

1 голос
/ 30 ноября 2010

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

После синтаксического анализа создается таблица символов, из которой генерируется фактический двоичный код.

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

http://en.wikipedia.org/wiki/Parsing

...