Создаем компилятор для своего языка программирования, Lexer

Создаем компилятор для своего языка программирования, Lexer

Немножко об основах компиляции программ, компиляцию можно разбить на 3 фазы:
  1. Разбиение на Token'ы
  2. Создание AST (абстрактного синтаксического дерева)
  3. Генерация кода

Немного поподробнее о каждой из фаз:
Разбиение на Token'ы - процесс преобразования кода в определенные единицы компилятора. Как правило их можно разделить на несколько типов:
  • Ключевые слова - keyword (`if`, `else`, `while`, `struct`, `class`...)
  • Операторы - operator (`+`, `-`, `=`, `-=`, `+=`)
  • Литералы - literal (нет, не либералы, а: `"строка"`, `1488`, `true`, `false`)
  • Пунктуация - punctuation (`{`, `}`, `[`, `,`)
  • Идентификаторы - identifier (имена функций, переменных, `main`, `x`)

Например, если разбить на токены следующий код на C

int main() {
    return 1;
}

Мы получим:

Identifier int
Identifier main
Punctuation (
Punctuation )
Punctuation {
Punctuation }
Keyword return
Punctuation ;

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

decl function
    name "main"
    arguments []
    body
        statement return
            value 1        

После, генератор проходится по каждому из узлов и создает код, объектный файл, который может быть скомпонован с аналогичными файлами C/C++ итд.
На самом деле фаза генерации очень сложна, так как там надо учитывать архитектуру, операционную систему, слава Аллаху, кто-то из программистов подумал:
А что если создать платформу, для создания компиляторов, которая будет предоставлять разработчикам интерфейс по созданию программ, а всю грязную низкоуровневую работу будет выполнять библиотека?

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

table entries. Here is an example of the “hello world” module:

; Declare the string constant as a global constant.
@.str = private unnamed_addr constant [13 x i8] c"hello world\0A\00"

; External declaration of the puts function
declare i32 @puts(i8* nocapture) nounwind

; Definition of main function
define i32 @main() {   ; i32()*
  ; Convert [13 x i8]* to i8*...
  %cast210 = getelementptr [13 x i8], [13 x i8]* @.str, i64 0, i64 0

  ; Call puts function to write out the string to stdout.
  call i32 @puts(i8* %cast210)
  ret i32 0
}

; Named metadata
!0 = !{i32 42, null, !"string"}
!foo = !{!0}

Так вот, теперь мы будем создавать свой ЯП.
Писать код придется на Rust'е, потому, что я так захотел.
Напишем основные перечисления:

//Думаю, тут все предельно ясно. Перечисления в Rust - декларация нового типа, 
// который может принимать одно из указанных значений. Как и в C. 
// Только в Rust у перечислений могут быть аргументы, что довольно круто.
enum Keyword {
	// `func`
	Func,
	// `let`
	Let,
	// `ret`
	Ret
}
enum Literal {
	// `123456`
	// Самое класнное, что в Rust'е у перечисления есть аргументы.
        Int(i32),
	// `123456.0`
	// `.0`
	Float(f64)
}

// Перечисление Token
enum Token {
	// Идентификатор
	Ident(String),
	// Ключевое слово
	Keyword(Keyword),
	// Литерал
	Literal(Literal),
	// Конец файла
	Eof
}


Теперь создадим класс (в Rust нет классов поэтому это будет структура) Lexer, отвечающий за преобразование кода в токены.

Теперь все это надо проверить, благо Rust поддерживает тесты

// Rust поддерживает тесты
#[cfg(test)]
mod tests {
	use super::*;

	#[test]
	fn simple_code() {
		// Задаем переменные
		let code = 
		"func main() 10";
		let mut lexer = Lexer::new(code);

		// Сравниваем получаемые значения
		assert_eq!(lexer.tokenize(), Token::Keyword(Keyword::Func));
		assert_eq!(lexer.tokenize(), Token::Ident("main".to_string()));
		assert_eq!(lexer.tokenize(), Token::Punct(Punct::OpenParen));
		assert_eq!(lexer.tokenize(), Token::Punct(Punct::CloseParen));
		assert_eq!(lexer.tokenize(), Token::Literal(Literal::Int(10)));
	}
}

Что-ж, мы создали простой лексер, в следущем гайде мы создадим парсер и небольшое дерево,
всем спасибо,

тавьте 5 мем это моя первая новость не судите строго
Реклама:




Голосуй за новость:
(+4.602,2-2.40)
  • Просмотров: 218
  • Комментариев: 8
Рекомендуемое для Вас:

  1. Посетители
    Зарегистрирован: 23.12.2018
    Репутация
    (0.000.0)
    Weline | Пользователь offline | (23 декабря 2018 17:17) | Комментариев: 1 | Новостей: 1 |
    • 0

    Научите html в новостях вставлять.


  2. Олдфаги
    Зарегистрирован: 16.01.2016
    Репутация
    (+144.3131,7-12.6)
    KAPTOXA | Пользователь offline | (23 декабря 2018 19:38) | Комментариев: 284 | Новостей: 14 |
    • 0

    Вроде интересно, ничего не понятно, 5 мем.
    -----------------------------------------------------------------------------
    Умные дома, чайники, машины, один ты тупой.


  3. Просто хорошие люди
    Зарегистрирован: 6.07.2018
    Репутация
    (+25.024,9-0.1)
    rubicus | Пользователь offline | (23 декабря 2018 19:52) | Комментариев: 94 | Новостей: 7 |
    • 0

    Интересно, но оформления нет.
    4 меме
    -----------------------------------------------------------------------------
    Linux майн


  4. Главные редакторы
    Зарегистрирован: 5.07.2012
    Репутация
    (+1225.91184,3-41.6)
    dedepete | Пользователь offline | (24 декабря 2018 01:10) | Комментариев: 847 | Новостей: 131 |
    • 0

    Цитата: Weline
    Наверняка, программируя в школе на Pascal'е у Вас возникала мысль:
    Кто создал этот дегенеративный язык программирования?

    Спасибо, что паскаль, а не пучина безысходности из плюсов.
    -----------------------------------------------------------------------------
    http://steam.pm/id/dedepete


    #FomenMustDie


  5. Модератор бездны
    Зарегистрирован: 10.09.2016
    Репутация
    (+376.4371,2-5.2)
    Sab | Пользователь offline | (24 декабря 2018 04:52) | Комментариев: 621 | Новостей: 49 |
    • 0

    Вопрос: зачем это на сайте по маинкрафту?
    Цитата: Weline
    Кто создал этот дегенеративный язык программирования?

    мда, сами Вы дегенерат, будто школьникам/студентам много надо от яп
    Цитата: Weline
    я нашел такой код, не знаю что он делает, но выглядет номрыч

    определенно хороший гайд
    -----------------------------------------------------------------------------
    the end


  6. Посетители
    Зарегистрирован: 23.07.2018
    Репутация
    (+2.21,3-0.9)
    Leonid073 | Пользователь offline | (28 декабря 2018 13:52) | Комментариев: 44 | Новостей: 5 |
    • 0

    Где комплятор html? (шутка)
    Отцентруйте новость.
    Статья интересная, на этом сайте страшна. 4 мем.
    -----------------------------------------------------------------------------
    делаю сборки серверов на заказ
    vk.com/leonid_malo


  7. Модератор бездны
    Зарегистрирован: 4.05.2014
    Репутация
    (+57.444,9-12.5)
    darlingdavis | Пользователь offline | (6 января 2019 10:26) | Комментариев: 111 | Новостей: 16 |
    • 0

    боже упаси
    -----------------------------------------------------------------------------
    Цитата: Dr_John_Watson
    бля я достал кружку с полки поставил ее кверх ногами и налил туда воды, ебать я долббаеб тупа весь мокрый



  8. Просто хорошие люди
    Зарегистрирован: 7.03.2016
    Репутация
    (+50.950,1-0.8)
    CheshirX | Пользователь offline | (11 января 2019 14:26) | Комментариев: 222 | Новостей: 14 |
    • 0

    Гм, гмм...
    Кто создал этот дегенеративный язык программирования?

    Я бы сказал так о Кумире, но не в этом суть
    ----------------------------------------------------------------
    В принципе тебе бы разобраться с оформлением, HTML`ом и CSS`ом и будет счастье для несведущих... Поменьше компрометирующих фразочек, аля
    Кто создал этот дегенеративный язык программирования?

    я нашел такой код, не знаю что он делает, но выглядет номрыч

    тавьте 5 мем это моя первая новость не судите строго

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

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

    4
    -----------------------------------------------------------------------------


Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.

Последние сообщения с форума

Название темы Автор Статистика Последнее сообщение
Краш с модом Draconic Evolution

Тема в разделе: Ваши вопросы по Minecraft

artem5647

Просмотров: 15

Ответов: 0

Автор: artem5647

Сегодня, 17:44

Форумный чат

Тема в разделе: Чат флудилка

3JIou_Kpunep

Просмотров: 7946396

Ответов: 136898

Автор: Voknehzyr

Сегодня, 16:40

SneakyCraft-Набирается народ на сервер

Тема в разделе: Корзина

MrSynes

Просмотров: 143

Ответов: 1

Автор: Father

Сегодня, 16:14

Проблема с модов flans mod

Тема в разделе: Ваши вопросы по Minecraft

DropX

Просмотров: 7736

Ответов: 18

Автор: VladKoBY

Сегодня, 11:47

Ищу напарника для совместной игры

Тема в разделе: Флудильня

Raylik

Просмотров: 136

Ответов: 3

Автор: SanSanich

Сегодня, 06:42