( +8.90 6,3 -2.60 )

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

Автор: Weline
Категория: Бездна
Создаем компилятор для своего языка программирования, 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 мем это моя первая новость не судите строго
  1. Посетители

    23 декабря 2018 17:17

    0

    Научите html в новостях вставлять.
  2. ТруЪ Олдфаги-с

    23 декабря 2018 19:38

    +1

    Вроде интересно, ничего не понятно, 5 мем.
  3. Просто хорошие люди

    23 декабря 2018 19:52

    0

    Интересно, но оформления нет.
    4 меме
  4. Главные редакторы

    24 декабря 2018 01:10

    -3

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

    Спасибо, что паскаль, а не пучина безысходности из плюсов.
  5. Модератор бездны

    24 декабря 2018 04:52

    0

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

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

    определенно хороший гайд
  6. Просто хорошие люди

    28 декабря 2018 13:52

    0

    Где комплятор html? (шутка)
    Отцентруйте новость.
    Статья интересная, на этом сайте страшна. 4 мем.
  7. Модератор бездны

    6 января 2019 10:26

    0

    боже упаси
  8. Олдфаги

    11 января 2019 14:26

    0

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

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

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

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

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

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

    4
  9. Посетители

    16 февраля 2019 16:23

    0

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

    15 марта 2019 07:42

    0

    сложно 5 мем
  11. Модератор

    19 марта 2019 20:42

    0

    извините я слишком тупой для всего этого
  12. Просто хорошие люди

    28 апреля 2019 08:54

    0

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


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

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

Название темы
Статистика
Последнее сообщение

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

Ответов: 18

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

Ответов: 6

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

Ответов: 679

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

Ответов: 1

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

Ответов: 1

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