Создаем компилятор для своего языка программирования, 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 мем это моя первая новость не судите строго

Голосуй за новость:
(+8.906,3-2.60)
  • Просмотров: 2 009
  • Комментариев: 12
Категория: Бездна
Рекомендуемое для Вас:

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

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


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

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


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

    Интересно, но оформления нет.
    4 меме


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

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

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


    #FomenMustDie


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

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

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

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


  6. Просто хорошие люди
    Зарегистрирован: 23.07.2018
    Репутация
    (+9.07,7-1.3)
    Leonid073 | Пользователь offline | (28 декабря 2018 13:52) | Комментариев: 114 | Новостей: 6 |
    • 0

    Где комплятор html? (шутка)
    Отцентруйте новость.
    Статья интересная, на этом сайте страшна. 4 мем.
    -----------------------------------------------------------------------------
    # dd if=/dev/mybrain of=/dev/ruminecraft


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

    боже упаси


  8. Олдфаги
    Зарегистрирован: 7.03.2016
    Репутация
    (+243.9243-0.9)
    CheshirX | Пользователь offline | (11 января 2019 14:26) | Комментариев: 707 | Новостей: 20 |
    • 0

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

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

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

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

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

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

    4
    -----------------------------------------------------------------------------
    Просто призрак студента аэрокоса


  9. Посетители
    Зарегистрирован: 29.09.2018
    Репутация
    (+0.20,20.0)
    bro_viskas | Пользователь offline | (16 февраля 2019 16:23) | Комментариев: 5 | Новостей: 0 |
    • 0

    Цитата: Weline
    я нашел такой код, не знаю что он делает, но выглядет номрыч
    хд
    -----------------------------------------------------------------------------
    Цитата: Weline
    я нашел такой код, не знаю что он делает, но выглядет номрыч



  10. Посетители
    Зарегистрирован: 10.06.2018
    Репутация
    (+10.29,4-0.8)
    sfagnum | Пользователь offline | (15 марта 2019 07:42) | Комментариев: 46 | Новостей: 1 |
    • 0

    сложно 5 мем
    -----------------------------------------------------------------------------
    Цитата: Ruslanzh
    Опять все скатилось до обсуждения членов.



  11. Модератор
    Зарегистрирован: 15.12.2014
    Репутация
    (+369.3334,2-35.1)
    chaj | Пользователь offline | (19 марта 2019 20:42) | Комментариев: 601 | Новостей: 17 |
    • 0

    извините я слишком тупой для всего этого
    -----------------------------------------------------------------------------



  12. Просто хорошие люди
    Зарегистрирован: 25.03.2018
    Репутация
    (+180.2179,2-1.0)
    AhpioxLit | Пользователь offline | (28 апреля 2019 08:54) | Комментариев: 204 | Новостей: 8 |
    • 0

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


    А тебе надо высоко-уровневый ассемблер с возможностью контролировать жёсткий диск?
    Паскаль работает и относительно быстро учится, и на этом спасибоDeterm

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

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

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

Тема в разделе: Техническая поддержка сайта

value_Stalker

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

Ответов: 5

Автор: value_Stalker

Сегодня, 00:16

Что-то с прицелом в modern warfare

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

PhantomX

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

Ответов: 5

Автор: maksgrodno

Вчера, 21:50

Java разработчик для написания модов/плагинов для minecraft.

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

Limbossiks

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

Ответов: 39

Автор: vovanhurcane

Вчера, 19:57

Помогите, пожалуйста, крашится сборка

Тема в разделе: Техническая поддержка сайта

KilzRait

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

Ответов: 0

Автор: KilzRait

Вчера, 19:01

Видео/Стримы канал Ritterydam

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

ritterydam

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

Ответов: 528

Автор: ritterydam

Вчера, 18:32

  • Ru-minecraft.ru
  • »
  • Бездна
  • »
  • Создаем компилятор для своего языка программирования, Lexer