Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Как	
  написать	
  
компилятор	
  	
  
за	
  15	
  минут?	
  
Андрей	
  Гершун	
  
AlaSQL	
  
Зачем	
  еще	
  языки	
  	
  
кроме	
  JavaScript?	
  
2	
  
Benjamin	
  Lee	
  Whorf	
  
Автор	
  гипотезы	
  	
  
лингви...
3	
  
Содержание	
  
•  Знакомьтесь	
  –	
  МАТRIX!	
  
•  Инструменты	
  
•  Орфография	
  
•  Грамматика	
  
•  Семантика	
  
...
Как	
  происходит	
  процесс	
  	
  
понимания	
  и	
  выполнения?	
  
•  Лексер	
  
•  Парсер	
  
•  Run-­‐cme	
  library...
Знакомьтесь,	
  
MATRIX!	
  
6	
  
MATRIX	
  
•  Язык	
  работы	
  с	
  матрицами	
  
•  Вдохновлен	
  MATLAB,	
  OCTANE,	
  R	
  и	
  Q	
  
	
  	
  	
  
	
 ...
Пример	
  программы	
  на	
  MATRIX	
  
A	
  =	
  1	
  2	
  3	
  
B	
  =	
  4|5|6	
  
PRINT	
  A*B	
  
•  Если	
  все	
  п...
Примитивы	
  
1	
  	
   	
   	
   	
   	
   	
  //	
  число	
  
1	
  2	
  3	
  4	
  	
   	
   	
  //	
  вектор-­‐строка	
 ...
Операции	
  МАТRIX	
  
1	
  2	
  +	
  3	
  4	
   	
   	
  //	
  =>	
  4	
  6	
  –	
  сложение	
  
2	
  *	
  5	
  6	
  	
  ...
Zach	
  Carter	
  
Автор	
  Jison	
  
Воспользуемся	
  	
  
генератором	
  	
  
парсеров:	
  
•  Jison	
  
	
  
Альтернати...
Структура	
  файла	
  	
  
с	
  грамматикой	
  (matrix0.jison)	
  
%{	
  /*	
  А.	
  Вспомогательный	
  код	
  */	
  %}	
 ...
Структура	
  файла	
  (продолжение)	
  
%ebnf	
  
%start	
  main	
  
/*	
  В.	
  Приоритеты	
  правил	
  */	
  
	
  
%%	
 ...
Слова	
  языка	
  
•  Комментарии	
  //	
  
•  Пробелы	
  
•  Число	
  
•  Названия	
  переменных	
  и	
  функций	
  
•  З...
Как	
  работает	
  лексер?	
  
	
  
a	
  =	
  1	
  2	
  3'	
  
	
  
15	
  
Описываем	
  лексемы	
  
регулярка	
   	
   	
   	
  return	
  'лексема'	
  
	
  
16	
  
Бритва	
  Оккама:	
  Отсекаем	
  все	
  
ненужное:	
  комментарии	
  и	
  пробелы	
  
	
  
//	
  Комментарии	
  
//.*$	
  ...
Ключевые	
  слова	
  
	
  
'PRINT'	
   	
   	
   	
   	
  return	
  'PRINT'	
  
'GO	
  TO'	
   	
   	
   	
   	
  return	
...
Числа	
  и	
  литералы	
  
(после	
  ключевых	
  слов!)	
  
	
  
/*	
  Числа	
  */	
  
[0-­‐9]+(.[0-­‐9]*)? 	
   	
   	
  ...
Немного	
  магии	
  	
  
(служебные	
  лексемы)	
  
/*	
  Конец	
  файла	
  */	
  
<<EOF>>	
   	
   	
   	
   	
  return	
...
Кофе-­‐брейк	
  1:	
  	
  
Что	
  выдает	
  на	
  выходе	
  лексер?	
  
•  Проверим	
  лексику:	
  
	
  >	
  jison	
  matr...
Теперь	
  грамматика!	
  
правило	
  
	
  :	
  набор	
  лексем	
  1	
  
	
  |	
  набор	
  лексем	
  2	
  
	
  |	
  набор	
...
Описываем	
  операторы	
  
main	
  
	
  :	
  Statement*	
  EOF	
  ;	
  
	
  
Statement	
  
	
  :	
  Print	
  |	
  Set	
  ;...
Выражения	
  
Expression	
  
	
  :	
  Matrix	
  
	
  |	
  LITERAL	
  
	
  |	
  LPAR	
  Expression	
  RPAR	
  
	
  |	
  Exp...
Матрицы	
  
Matrix	
  
	
  :	
  Columns	
  
	
  ;	
  
Row	
  
	
  :	
  NUMBER	
  
	
  |	
  Row	
  NUMBER	
  
	
  ;	
  
Col...
Приоритеты	
  операций	
  
	
  
%left	
  PLUS	
   	
   	
   	
   	
  //	
  	
  1	
  +	
  2	
  +	
  3	
  
%left	
  STAR	
  ...
Кофе-­‐брейк	
  2:дерево	
  разбора	
  
a	
  =	
  1	
  2	
  3'	
  
27	
  
Пора	
  уже	
  что-­‐то	
  делать!	
  
Компилируем	
  грамматику	
  
	
  >	
  jison	
  matrix2.jison	
  
	
  
Выполняем	
 ...
Пишем	
  	
  
интерпретатор!	
  
29	
  
C3P0	
  
интерпретатор	
  
Подготовимся	
  интерпретировать	
  
(run-­‐cme	
  library	
  MATRIX)	
  
•  Операторы	
  
– MATRIX.print()	
  
•  Операци...
Добавляем	
  семантику:	
  	
  
подставляем	
  лексемы	
  
Правило	
  	
  
:	
  Expression	
  PLUS	
  Expression	
  	
  
	...
Начнем	
  с	
  печати!	
  
Print	
  	
  
	
  :	
  PRINT	
  Expression	
  	
  
	
   	
  {	
  MATRIX.print($2);	
  }	
  
	
 ...
Присваивание	
  переменной	
  
Set	
  	
  
	
  :	
  LITERAL	
  EQ	
  Expression	
  
	
   	
  {	
  MATRIX.mem[$1]	
  =	
  $...
Матрица	
  
Внутреннее	
  представление	
  –	
  массив	
  
массивов,	
  например,	
  матрица:	
  
	
  	
  	
  	
  1	
  2	
...
 Строки	
  и	
  столбцы	
  матрицы	
  
/*	
  1	
  2	
  3	
  */	
  
Row	
  
	
  :	
  NUMBER	
  
	
   	
  {	
  $$	
  =	
  [p...
И	
  все	
  -­‐	
  интерпретатор	
  готов!	
  
	
  
36	
  
Кофе-­‐брейк	
  3:	
  Настоящий	
  запуск!	
  
>	
  jison	
  matrix3.jison	
  
>	
  node	
  matrix3	
  program.mat	
  
	
 ...
38	
  
Розеттский	
  камень	
  Жан-­‐Франсуа	
  Шампольон	
  
(транслятор)	
  
Интерпретатор	
  
Возвращает	
  значение:	
  
	
  
Expression	
  PLUS	
  Expression	
  
{	
  $$	
  =	
  MATRIX.add($1,$3);...
А	
  компилятор…	
  
Возвращает	
  строку	
  кода	
  на	
  JavaScript:	
  
	
  
Expression	
  PLUS	
  Expression	
  
{	
  ...
Главная	
  функция	
  интерпретатора	
  
Ничего	
  не	
  возвращает	
  
	
  
main	
  
	
  :	
  Statement*	
  EOF;	
  
	
  ...
Главная	
  функция	
  компилятора	
  
Возвращает	
  откомпилированную	
  функцию	
  
на	
  JavaScript:	
  
	
  
main	
  
	...
Праздничный	
  ужин!	
  
Компилируем	
  грамматику	
  
>	
  jison	
  matrix4.jison	
  
	
  
//	
  Запуск	
  из	
  JavaScri...
В	
  браузере	
  
<script	
  src="matrix4.js"></script>	
  
<script>	
  
	
  var	
  f	
  =	
  parse.parse('print	
  1	
  2...
Итак,	
  для	
  интерпретатора/
компилятора	
  нужно:	
  
•  Определить	
  лексемы	
  
•  Определить	
  правила	
  
•  Раз...
Хотите	
  написать	
  свой	
  ES6?	
  
•  Парсеры	
  JavaScript	
  
– Esprima	
  
– Acorn	
  
– UglifyJS	
  
– SpiderMonke...
47	
  
	
  
Андрей	
  Гершун	
  	
  	
  agershun@gmail.com	
  
h˜p://github.com/agershun/matrix	
  
	
  
Upcoming SlideShare
Loading in …5
×
Upcoming SlideShare
Анализ текста на естественном языке, управляемый вариантами разбора
Next
Download to read offline and view in fullscreen.

2

Share

Download to read offline

"Как написать компилятор за 15 минут", Андрей Гершун, MoscowJS 24

Download to read offline

Слайды доклада "Как написать компилятор за 15 минут", Андрей Гершун, MoscowJS 24

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

"Как написать компилятор за 15 минут", Андрей Гершун, MoscowJS 24

  1. 1. Как  написать   компилятор     за  15  минут?   Андрей  Гершун   AlaSQL  
  2. 2. Зачем  еще  языки     кроме  JavaScript?   2   Benjamin  Lee  Whorf   Автор  гипотезы     лингвистической  относительности   (категории  языка  определяют     категории  мышления)  
  3. 3. 3  
  4. 4. Содержание   •  Знакомьтесь  –  МАТRIX!   •  Инструменты   •  Орфография   •  Грамматика   •  Семантика   •  Пишем  интерпретатор   •  Венец  творения    –  компилятор!   4  
  5. 5. Как  происходит  процесс     понимания  и  выполнения?   •  Лексер   •  Парсер   •  Run-­‐cme  library   •  Интерпретатор   или   •  Компилятор   5   C3P0   интерпретатор  
  6. 6. Знакомьтесь,   MATRIX!   6  
  7. 7. MATRIX   •  Язык  работы  с  матрицами   •  Вдохновлен  MATLAB,  OCTANE,  R  и  Q                  c  =    a  *  b'   7  
  8. 8. Пример  программы  на  MATRIX   A  =  1  2  3   B  =  4|5|6   PRINT  A*B   •  Если  все  правильно,     то  мы  должны  увидеть:  32   8  
  9. 9. Примитивы   1              //  число   1  2  3  4        //  вектор-­‐строка   1  |  2  |  3      //  вектор-­‐столбец   1  2  |  3  4      //  матрица  2x2     9  
  10. 10. Операции  МАТRIX   1  2  +  3  4      //  =>  4  6  –  сложение   2  *  5  6          //  =>  10  12  –  умножение   1  2'                //  =>  1|2  -­‐транспонирование   (1  2  +  3  4)*2  //  =>  8  12  -­‐  скобки   size(1  2|3  4)  //  =>  2  2  -­‐  функция  размера   10  
  11. 11. Zach  Carter   Автор  Jison   Воспользуемся     генератором     парсеров:   •  Jison     Альтернативы:   •  PEG.js   •  ALTNR/4     11  
  12. 12. Структура  файла     с  грамматикой  (matrix0.jison)   %{  /*  А.  Вспомогательный  код  */  %}     %lex   %options  case-­‐insensitive   %%   /*  Б.  Лексемы  */   /lex   12  
  13. 13. Структура  файла  (продолжение)   %ebnf   %start  main   /*  В.  Приоритеты  правил  */     %%   /*  Г.  Грамматические  правила    */   13  
  14. 14. Слова  языка   •  Комментарии  //   •  Пробелы   •  Число   •  Названия  переменных  и  функций   •  Знаки:  +  *  ‘  =  (  )     •  Ключевое  слово:  PRINT   •  Конец  файла:  <<EOF>>   14  
  15. 15. Как  работает  лексер?     a  =  1  2  3'     15  
  16. 16. Описываем  лексемы   регулярка        return  'лексема'     16  
  17. 17. Бритва  Оккама:  Отсекаем  все   ненужное:  комментарии  и  пробелы     //  Комментарии   //.*$        return     //  Пробелы,  переносы  строк   s            return   17  William  of  Okkam  
  18. 18. Ключевые  слова     'PRINT'          return  'PRINT'   'GO  TO'          return  'GOTO'       Синонимы   'GOTO'            return  'GOTO'   18  
  19. 19. Числа  и  литералы   (после  ключевых  слов!)     /*  Числа  */   [0-­‐9]+(.[0-­‐9]*)?      return  'NUMBER'     /*  Литералы:  названия  переменных  и   функций  */   [A-­‐Za-­‐z_][A-­‐Za-­‐z_0-­‐9]*  return  'LITERAL'   19  
  20. 20. Немного  магии     (служебные  лексемы)   /*  Конец  файла  */   <<EOF>>          return  'EOF'     /*  В  конце  отлавливаем   нераспознанные  символы  */   .                return  'INVALID'     20  
  21. 21. Кофе-­‐брейк  1:     Что  выдает  на  выходе  лексер?   •  Проверим  лексику:    >  jison  matrix1.jison   •  Отладим  с  помощью  jison-­‐debugger     a  =  1  2  3'   21  
  22. 22. Теперь  грамматика!   правило    :  набор  лексем  1    |  набор  лексем  2    |  набор  лексем  3    ;   22            John  Backus   Peter  Naur  
  23. 23. Описываем  операторы   main    :  Statement*  EOF  ;     Statement    :  Print  |  Set  ;     Set      :  LITERAL  EQ  Expression  ;     Print    :  PRINT  Expression  ;   a  =  1  2  3     PRINT  A*b'   23  
  24. 24. Выражения   Expression    :  Matrix    |  LITERAL    |  LPAR  Expression  RPAR    |  Expression  PLUS  Expression    |  Expression  STAR  Expression    |  Expression  SHTRIH    ;   24  
  25. 25. Матрицы   Matrix    :  Columns    ;   Row    :  NUMBER    |  Row  NUMBER    ;   Columns    :  Row    |  Columns  PALKA  Row    ;   •  Пример  1  2  3   25  
  26. 26. Приоритеты  операций     %left  PLUS          //    1  +  2  +  3   %left  STAR          //      1  +  2  *  3   %right  STRIH        //    1  2  *  3  4'     26  
  27. 27. Кофе-­‐брейк  2:дерево  разбора   a  =  1  2  3'   27  
  28. 28. Пора  уже  что-­‐то  делать!   Компилируем  грамматику    >  jison  matrix2.jison     Выполняем  проверку  грамматики    >  node  matrix2.js  program.mat     Если  все  правильно,  то  ничего  не   будет!   28  
  29. 29. Пишем     интерпретатор!   29   C3P0   интерпретатор  
  30. 30. Подготовимся  интерпретировать   (run-­‐cme  library  MATRIX)   •  Операторы   – MATRIX.print()   •  Операции   – MATRIX.add()   – MATRIX.mulcply()   – MATRIX.transpose()   30  
  31. 31. Добавляем  семантику:     подставляем  лексемы   Правило     :  Expression  PLUS  Expression      {      //  $$  -­‐  возвращаемая  переменная      //    $1,  $2…  -­‐  лексемы        $$  =  $1  +  $3;    }    ;   31  
  32. 32. Начнем  с  печати!   Print      :  PRINT  Expression        {  MATRIX.print($2);  }    ;   32  
  33. 33. Присваивание  переменной   Set      :  LITERAL  EQ  Expression      {  MATRIX.mem[$1]  =  $3;  }    ;     //  Когда  будем  забирать  значение,     //  просто  возьмем:      MATRIX.mem.a   33  
  34. 34. Матрица   Внутреннее  представление  –  массив   массивов,  например,  матрица:          1  2  3  |  4  5  6     Представляется  как:      [[1,2,3],[4,5,6]]         34  
  35. 35.  Строки  и  столбцы  матрицы   /*  1  2  3  */   Row    :  NUMBER      {  $$  =  [parseFloat($1)];  }    |  Row  NUMBER      {  $$  =  $1;  $$.push(parseFloat($2));  }    ;     /*  1  2  |  3  4  */   Columns    :  Row      {  $$  =  [$1];  }    |  Columns  PALKA  Row      {  $$  =  $1;  $$.push($3);  }    ;   35  
  36. 36. И  все  -­‐  интерпретатор  готов!     36  
  37. 37. Кофе-­‐брейк  3:  Настоящий  запуск!   >  jison  matrix3.jison   >  node  matrix3  program.mat     Voila!   …  наша  матрица!   37  
  38. 38. 38   Розеттский  камень  Жан-­‐Франсуа  Шампольон   (транслятор)  
  39. 39. Интерпретатор   Возвращает  значение:     Expression  PLUS  Expression   {  $$  =  MATRIX.add($1,$3);  }     39  
  40. 40. А  компилятор…   Возвращает  строку  кода  на  JavaScript:     Expression  PLUS  Expression   {  $$  =  'MATRIX.add('+$1+','+$3+')';  }       40  
  41. 41. Главная  функция  интерпретатора   Ничего  не  возвращает     main    :  Statement*  EOF;           41  
  42. 42. Главная  функция  компилятора   Возвращает  откомпилированную  функцию   на  JavaScript:     main    :  Statement*  EOF      {  return  new  Function(                  'var  MATRIX  =  this;’                  +$1.join(';'))              .bind(MATRIX);  }    ;     42  
  43. 43. Праздничный  ужин!   Компилируем  грамматику   >  jison  matrix4.jison     //  Запуск  из  JavaScript   var  parser  =  require('./matrix4.js');   var  f  =  parser.parse('print  1  2+100');     f();   //вернет  101  102   43  
  44. 44. В  браузере   <script  src="matrix4.js"></script>   <script>    var  f  =  parse.parse('print  1  2+100');    f();   </script>     44  
  45. 45. Итак,  для  интерпретатора/ компилятора  нужно:   •  Определить  лексемы   •  Определить  правила   •  Разработать  runcme  библиотеку   •  Определить  семантику  (как  будут   интерпретироваться  или  компилироваться   правила)   45  
  46. 46. Хотите  написать  свой  ES6?   •  Парсеры  JavaScript   – Esprima   – Acorn   – UglifyJS   – SpiderMonkey   •  Линтеры  –  используют  парсеры   •  CoffeeScript  –  использует  Jison   46  
  47. 47. 47     Андрей  Гершун      agershun@gmail.com   h˜p://github.com/agershun/matrix    
  • MaximSmolyakov

    Feb. 7, 2017
  • ssuser4d010f

    Aug. 7, 2015

Слайды доклада "Как написать компилятор за 15 минут", Андрей Гершун, MoscowJS 24

Views

Total views

1,019

On Slideshare

0

From embeds

0

Number of embeds

6

Actions

Downloads

3

Shares

0

Comments

0

Likes

2

×