Путь от текста программы к исполняемому коду

Лексемы

Существуют следующие виды лексем:

  • имена (идентификаторы);
  • ключевые слова;
  • знаки операций;
  • разделители;
  • литералы (константы).

Границы лексем определяются другими лексемами, такими, как разделители или знаки операций.

Лексемы языка программирования аналогичны словам естественного языка. Например, лексемами являются константа 128 (но не ее часть 12), имя Vasia, ключевое слово goto и знак операции сложения +. Из лексем составляются выражения и операторы.

  • Выражение задает правило вычисления некоторого значения. Например, выражение a + b задает правило вычисления суммы величин a и b.
  • Оператор задает законченное описание некоторого действия.

Операторы делят на исполняемые и неисполняемые, простые и составные. Исполняемые операторы задают действия над данными. Неисполняемые операторы служат для описания данных, поэтому их часто называют операторами описания или просто описаниями. Например, int a ; - это оператор описания целочисленной переменной a.

Составной оператор или блок - это группа операторов, заключенная в фигурные скобки. Блоки могут быть вложенными.

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

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

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

Сначала исходный текст программы обрабатывается препроцессором. Он разыскивает в тексте программы "свои" директивы (инструкции, команды), которые начинаются с символа # ("решетка"), и выполняет их. Директивы препроцессора позволяют вставить в программу тексты из других файлов, исключить из процесса компиляции фрагменты кода или выполнить замену одних фрагментов другими.

Обработанный препроцессором текст программы (в стандарте С++ он называется "единица компиляции") передается компилятору, который выполняет лексический и синтаксический анализ. На фазе лексического анализа лексический анализатор ( сканер ) последовательно просматривает поступающий на его вход поток символов, составляющих исходный текст программы, и выделяет допустимые лексемы. Их границы определяются по разделителям, пробельным символам и другим лексемам.

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

Если ошибок в программе не обнаружено, выполняется фаза генерации кода.Конкретный вид кода зависит от того, приложение какого типа мы создаем: Windows или . NET. Если это обычное приложение Windows, то строится объектный модуль - заготовка исполняемой программы в машинных кодах. Для приложения . NET формируется код на системно-независимом языке CIL.

Дальнейшая судьба этого кода также зависит от типа создаваемого приложения. Для обычного приложения Windows компоновщик (синонимы - линкер, редактор связей) формирует исполняемый модуль программы, подключая к объектному модулю другие объектные модули, в том числе содержащие элементы стандартных библиотек, которые используются в любой программе (например, для выполнения вывода на экран). Если программа состоит из нескольких исходных файлов, они компилируются по отдельности и объединяются на этапе компоновки. Исполняемый модуль имеет расширение . exe и запускается на выполнение обычным образом.

Приложение . NET собирается в сборку компоновщиком сборки и запускается на выполнение под управлением виртуальной машины CLR. При создании . NET -приложений также имеется возможность компилировать отдельно несколько модулей программы, собирая их потом в одну сборку.