Джек Креншоу - Давайте создадим компилятор!

Здесь есть возможность читать онлайн «Джек Креншоу - Давайте создадим компилятор!» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Жанр: Программирование, на русском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Давайте создадим компилятор!: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Давайте создадим компилятор!»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

Эта серия, написанная в период с 1988 по 1995 года и состоящая из шестнадцати частей, является нетехническим введением в конструирование компиляторов. Серия является руководством по теории и практике разработки синтаксических анализаторов и компиляторов языков программирования. До того как вы закончите чтение этой книги, вы раскроете каждый аспект конструирования компиляторов, разработаете новый язык программирования и создадите работающий компилятор.

Давайте создадим компилятор! — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Давайте создадим компилятор!», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Альтернативой является назначение вторичного регистра, в качестве которого я выбрал R7. (Почему не R1? Потому, что для других регистров у меня есть планы на будущее.)

Первый шаг в этой новой структуре – представить процедуру Pop, аналогичную Push. Эта процедура будет всегда выталкивать верхний элемент стека в D7:

{–}

{ Pop Stack into Secondary Register }

procedure Pop(Size: char);

begin

Move(Size, '(SP)+', 'D7');

end;

{–}

Общая идея состоит в том, что все «Pop-Op» подпрограммы могут вызывать ее. Когда это сделано, мы будем иметь оба операнда в регистрах, поэтому мы можем перевести любой нужный нам. Для работы процедуре Convert необходим другой аргумент, имя регистра:

{–}

{ Convert a Data Item from One Type to Another }

procedure Convert(Source, Dest: char; Reg: String);

begin

if Source <> Dest then begin

if Source = 'B' then

EmitLn('AND.W #$FF,' + Reg);

if Dest = 'L' then

EmitLn('EXT.L ' + Reg);

end;

end;

{–}

Следующая функция выполняет пребразование, но только если текущий тип T1 меньше по размеру, чем желаемый тип T2. Это функция, возвращающая конечный тип, позволяющий нам знать, что она решила:

{–}

{ Promote the Size of a Register Value }

function Promote(T1, T2: char; Reg: string): char;

var Typ: char;

begin

Typ := T1;

if T1 <> T2 then

if (T1 = 'B') or ((T1 = 'W') and (T2 = 'L')) then begin

Convert(T1, T2, Reg);

Typ := T2;

end;

Promote := Typ;

end;

{–}

Наконец, следующая функция приводит два регистра к одному типу:

{–}

{ Force both Arguments to Same Type }

function SameType(T1, T2: char): char;

begin

T1 := Promote(T1, T2, 'D7');

SameType := Promote(T2, T1, 'D0');

end;

{–}

Эти новые подпрограммы дают нам заряд, необходимы нам чтобы разложить PopAdd и PopSub:

{–}

{ Generate Code to Add Primary to the Stack }

function PopAdd(T1, T2: char): char;

begin

Pop(T1);

T2 := SameType(T1, T2);

GenAdd(T2);

PopAdd := T2;

end;

{–}

{ Generate Code to Subtract Primary from the Stack }

function PopSub(T1, T2: char): char;

begin

Pop(T1);

T2 := SameType(T1, T2);

GenSub(T2);

PopSub := T2;

end;

{–}

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

Обратите внимание на две новые подпрограммы генерации кода GenAdd и GenSub. Они являются остаточной формой оригинальных PopAdd и PopSub. Т.е. они являются чистыми генераторами кода, производящими сложение и вычитание регистров:

{–}

{ Add Top of Stack to Primary }

procedure GenAdd(Size: char);

begin

EmitLn('ADD.' + Size + ' D7,D0');

end;

{–}

{ Subtract Primary from Top of Stack }

procedure GenSub(Size: char);

begin

EmitLn('SUB.' + Size + ' D7,D0');

EmitLn('NEG.' + Size + ' D0');

end;

{–}

ОК, я соглашусь с вами: я выдал вам множество подпрограмм с тех пор, как мы в последний раз протестировали код. Но вы должны признать, что каждая новая подпрограмма довольно проста и ясна. Если вам (как и мне) не нравится тестировать так много новых подпрограмм одновременно все в порядке. Вы можете заглушить подпрограммы типа Convert, Promote и SameType так как они не считывают входной поток. Вы не получите корректный код, конечно, но программа должна работать. Затем постепенно расширяйте их.

При тестировании программы не забудьте, что вы сначала должны объявить некоторые переменные а затем начать «тело» программы с "B" в верхнем регистре (для BEGIN). Вы должны обнаружить, что синтаксический анализатор обрабатывает любые аддитивные выражения. Как только все подпрограммы преобразования будет введены, вы должны увидеть, что генерируется правильный код и код для преобразования типов вставляется в нужных местах. Попробуйте смешивать переменные различных размеров а также литералы. Удостоверьтесь, что все работает правильно. Как обычно, хорошо было бы попробовать некоторые ошибочные выражения и посмотреть, как компилятор обрабатывает их.

ПОЧЕМУ ТАК МНОГО ПРОЦЕДУР?

К этому моменту вы можете подумать, что я зашел слишком далеко в смысле глубоко вложенных процедур. В этом несомненно есть большие накладные расходы. Но в моем безумии есть смысл. Как в случае с UnOp, я заглядываю вперед на время, когда мы захотим генерировать лучший код. С таким способом организации кода мы можем достичь этого без значительных изменений в программе Например, в случаях, где значение помещенное в стек не должно преобразовываться, все же лучше использовать инструкцию «вытолкнуть и сложить». Если мы решим проверять такие случаи, мы можем включить дополнительные тесты в PopAdd и PopSub не изменяя что-либо еще.

МУЛЬТИПЛИКАТИВНЫЕ ВЫРАЖЕНИЯ

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

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Давайте создадим компилятор!»

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


Отзывы о книге «Давайте создадим компилятор!»

Обсуждение, отзывы о книге «Давайте создадим компилятор!» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x