Anúncio

Mais conteúdo relacionado

Similar a Transpile it.pdf(20)

Último(20)

Anúncio

Transpile it.pdf

  1. Трудности перевода переводим код между языками весело и задорно
  2. Приветствие
  3. Что сегодня будет? Минутка самолюбования Общая информация про методы парсинга Пример из жизни: как я писал транспайлер из typescript в php
  4. АВТФ,2010 Вычислительные комплексы системы и сети Системная аналитика
  5. Как понять,что мне нужен транспилятор?
  6. Из чего состоит ЯП? Токены: литералы,операторы,ключевые слова Лексический акцептор/анализатор Синтаксические конструкции: условные операторы, функции,классы Синтаксический акцептор/анализатор Семантика: смысл,который несет в себе код,выраженный в виде синтаксических конструкций ???
  7. Лексический анализатор 1 1 + + 2 2 // [NumericLiteral, PlusToken, NumericLiteral] // [NumericLiteral, PlusToken, NumericLiteral] x x = = y y // [Identifier, EqualToken, Idenitifer] // [Identifier, EqualToken, Idenitifer] let let x x = = y y. .toString toString( () ) /* [ /* [ LetKeyword, Identifier, EqualToken, LetKeyword, Identifier, EqualToken, Identifier, DotToken, Identifier, Identifier, DotToken, Identifier, OpenParenToken, CloseParenToken OpenParenToken, CloseParenToken ] */ ] */
  8. Синтаксический анализатор x x = = y y. .toString toString( () ) AssignmentExpression AssignmentExpression { { identifier identifier: : Identifier Identifier { { text text: : 'x' 'x' } }, , expression expression: : CallExpression CallExpression { { args args: : [ [] ], , expression expression: : PropertyAccessExpression PropertyAccessExpression { { property property: : Identifier Identifier { { text text: : 'toString' 'toString' } }, , expression expression: : Identifier Identifier { { text text: : 'y' 'y' } } } } } } } }
  9. А что дальше? Преобразование AST Генерация кода по AST Оптимизации времени компиляции Виртуальная машина JIT ....
  10. Alphabet Alphabet = = [ [OpenTag OpenTag, , ClosingTag ClosingTag, , Literal Literal] ] S S - -> > OpenTag OpenTag S S ClosingTag ClosingTag S S - -> > Literal Literal 1 1 text text 2 2 < <div div> >text text</ </div div> > 3 3 < <div div> >< <span span> >< <a a> >text text</ </a a> ></ </span span> ></ </div div> > 4 4 < <span span> >text text</ </div div> > 5 5 < <span span> >< <div div> >text text</ </lol lol> ></ </kek kek> > 6 6 < <div div> >text text</ </div div> >< <span span> >text text</ </span span> >
  11. // x = y.toString() // x = y.toString() AssignmentExpression AssignmentExpression { { id id: : Identifier Identifier { { text text: : 'x' 'x' } }, , expr expr: : CallExpression CallExpression { { args args: : [ [] ], , expr expr: : PropertyAccessExpression PropertyAccessExpression { { prop prop: : Identifier Identifier { { text text: : 'toString' 'toString' } }, , expr expr: : Identifier Identifier { { text text: : 'y' 'y' } } } } } } } }
  12. // x = y.toString() // x = y.toString() AssignmentExpression AssignmentExpression { { id id: : Identifier Identifier { { text text: : 'x' 'x' } }, , expr expr: : CallExpression CallExpression { { args args: : [ [] ], , expr expr: : PropertyAccessExpression PropertyAccessExpression { { prop prop: : Identifier Identifier { { text text: : 'toString' 'toString' } }, , expr expr: : Identifier Identifier { { text text: : 'y' 'y' } } } } } } } } 1 1 function function render render( (node node) ) { { 2 2 switch switch ( (node node. .kind kind) ) { { 3 3 case case AssignmentExpression AssignmentExpression: : 4 4 const const id id = = render render( (node node. .id id) ); ; 5 5 const const expr expr = = render render( (node node. .expr expr) ); ; 6 6 return return ` `(set (set ${ ${id id} } ${ ${expr expr} }) )` `; ; 7 7 case case Identifier Identifier: : // terminal - trivial! // terminal - trivial! 8 8 return return node node. .text text; ; 9 9 case case CallExpression CallExpression: : 10 10 if if ( ( 11 11 node node. .expr expr. .kind kind === === PropertyAccessExpression PropertyAccessExpression && && 12 12 node node. .expr expr. .prop prop. .text text === === 'toString' 'toString' 13 13 ) ) { { 14 14 const const expr expr = = render render( (node node. .expr expr. .expr expr) ); ; // oof // oof 15 15 return return ` `(write-to-string (write-to-string ${ ${expr expr} }) )` `; ; 16 16 } } 17 17 } } 18 18 } } 19 19 20 20 render render( (assignment assignment) ); ; // (set x (write-to-string y)) // (set x (write-to-string y))
  13. Предыстория
  14. Шо таки делать если на бэкенде у вас нет JS? Поставить nodejs ¯_(ツ)_/¯ Запихнуть рантайм v8 в этот ваш php/kphp GraalVM? А что если взять JS и сделать из него PHP?
  15. Допущения и ограничения Код на выходе не обязан соответствовать коду на входе. Для скорости можно ставить цель не поддерживать все возможные конструкции языка,т.е. ограничиться подмножеством языка. Околостатическая типизация 😨
  16. Что решили? Используем Typescript compiler API ...Не то что бы был какой-то иной выбор помимо typescript для языка реализации Инструменты для работы с AST у нас будут из коробки,что приятно Не пытаемся трансформировать AST,пишем сразу генератор кода
  17. Общая схема генерации кода yes no Start renderNode is terminal? Print as text Custom render logic
  18. Вернемся к примеру // x = y.toString() // x = y.toString() AssignmentExpression AssignmentExpression { { id id: : Identifier Identifier { { text text: : 'x' 'x' } }, , expr expr: : CallExpression CallExpression { { args args: : [ [] ], , expr expr: : PropertyAccessExpression PropertyAccessExpression { { prop prop: : Identifier Identifier { { text text: : 'toString' 'toString' } }, , expr expr: : Identifier Identifier { { text text: : 'y' 'y' } } } } } } } } function function render render( (node node) ) { { switch switch ( (node node. .kind kind) ) { { case case AssignmentExpression AssignmentExpression: : const const id id = = render render( (node node. .id id) ); ; const const expr expr = = render render( (node node. .expr expr) ); ; return return ` `${ ${id id} } = = ${ ${expr expr} }` `; ; case case Identifier Identifier: : // terminal - trivial! // terminal - trivial! return return '$' '$' + + node node. .text text; ; case case CallExpression CallExpression: : if if ( ( node node. .expr expr. .kind kind === === PropertyAccessExpression PropertyAccessExpression && && node node. .expr expr. .prop prop. .text text === === 'toString' 'toString' ) ) { { const const expr expr = = render render( (node node. .expr expr. .expr expr) ); ; // oof // oof return return ` `(string)( (string)(${ ${expr expr} }) )` `; ; } } } } } } render render( (assignment assignment) ); ; // $x = (string)($y) // $x = (string)($y)
  19. Непринужденное демо
  20. А что там с внедрением?
  21. Ресурсы Ахо,Ульман: Компиляторы Карпов: Основы построения трансляторов GNU Tools: Lex Bison JS Tools: Typescript compiler Espree
  22. Спасибо за внимание! Олег Клименко Mailto: me@ctizen.dev https://github.com/ctizen
Anúncio