SlideShare une entreprise Scribd logo
1  sur  26
Télécharger pour lire hors ligne
Трудности перевода
переводим код между языками
весело и задорно
Приветствие
Что сегодня
будет?
Минутка самолюбования
Общая информация про методы парсинга
Пример из жизни: как я писал транспайлер из
typescript в php
АВТФ,2010
Вычислительные комплексы системы и сети
Системная аналитика
Как понять,что мне
нужен транспилятор?
Из чего
состоит ЯП?
Токены: литералы,операторы,ключевые слова
Лексический акцептор/анализатор
Синтаксические конструкции: условные операторы,
функции,классы
Синтаксический акцептор/анализатор
Семантика: смысл,который несет в себе код,выраженный в
виде синтаксических конструкций
???
Лексический анализатор
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
] */
] */
Синтаксический анализатор
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' }
}
}
}
}
}
}
}
А что дальше?
Преобразование AST
Генерация кода по AST
Оптимизации времени компиляции
Виртуальная машина
JIT
....
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>
>
// 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'
}
}
}
}
}
}
}
}
// 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))
Предыстория
Шо таки делать если на бэкенде у
вас нет JS?
Поставить nodejs ¯_(ツ)_/¯
Запихнуть рантайм v8 в этот ваш php/kphp
GraalVM?
А что если взять JS и сделать из него PHP?
Допущения и ограничения
Код на выходе не обязан соответствовать коду на входе.
Для скорости можно ставить цель не поддерживать все возможные конструкции языка,т.е.
ограничиться подмножеством языка.
Околостатическая типизация 😨
Что решили?
Используем Typescript compiler API
...Не то что бы был какой-то иной выбор помимо typescript для языка реализации
Инструменты для работы с AST у нас будут из коробки,что приятно
Не пытаемся трансформировать AST,пишем сразу генератор кода
Общая схема генерации кода
yes
no
Start renderNode
is terminal?
Print as text
Custom render logic
Вернемся к примеру
// 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)
Непринужденное демо
А что там с внедрением?
Ресурсы
Ахо,Ульман: Компиляторы
Карпов: Основы построения трансляторов
GNU Tools:
Lex
Bison
JS Tools:
Typescript compiler
Espree
Спасибо за
внимание!
Олег Клименко
Mailto: me@ctizen.dev
https://github.com/ctizen

Contenu connexe

Similaire à Transpile it.pdf

Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй этоRoman Dvornov
 
Универсальный сигнатурный анализ кода на C#, Java, PHP
Универсальный сигнатурный анализ кода на C#, Java, PHPУниверсальный сигнатурный анализ кода на C#, Java, PHP
Универсальный сигнатурный анализ кода на C#, Java, PHPИван Кочуркин
 
Ф'Yii'лософия
Ф'Yii'лософияФ'Yii'лософия
Ф'Yii'лософияPaul Klimov
 
О сложностях программирования, или C# нас не спасет?
О сложностях программирования, или C# нас не спасет?О сложностях программирования, или C# нас не спасет?
О сложностях программирования, или C# нас не спасет?Tatyanazaxarova
 
Как выглядит современный фронтенд
Как выглядит современный фронтендКак выглядит современный фронтенд
Как выглядит современный фронтендTimophy Chaptykov
 
functional patterns - dotnetconf'11
functional patterns - dotnetconf'11functional patterns - dotnetconf'11
functional patterns - dotnetconf'110xffAA
 
Зачем обычному программисту знать языки, на которых почти никто не пишет. Але...
Зачем обычному программисту знать языки, на которых почти никто не пишет. Але...Зачем обычному программисту знать языки, на которых почти никто не пишет. Але...
Зачем обычному программисту знать языки, на которых почти никто не пишет. Але...yaevents
 
Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"Fwdays
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey TeplyakovAlex Tumanoff
 
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)Mikhail Kurnosov
 
Лекция 7: Фибоначчиевы кучи (Fibonacci heaps)
Лекция 7: Фибоначчиевы кучи (Fibonacci heaps)Лекция 7: Фибоначчиевы кучи (Fibonacci heaps)
Лекция 7: Фибоначчиевы кучи (Fibonacci heaps)Mikhail Kurnosov
 
20090720 hpc exercise1
20090720 hpc exercise120090720 hpc exercise1
20090720 hpc exercise1Michael Karpov
 
Solit 2014, Минусы ООП на примере языка PHP, Соловей Василий
Solit 2014, Минусы ООП на примере языка PHP, Соловей ВасилийSolit 2014, Минусы ООП на примере языка PHP, Соловей Василий
Solit 2014, Минусы ООП на примере языка PHP, Соловей Василийsolit
 
2. Операторы языка C#
2. Операторы языка C#2. Операторы языка C#
2. Операторы языка C#Olga Maksimenkova
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMTech Talks @NSU
 

Similaire à Transpile it.pdf (20)

Rgsu04
Rgsu04Rgsu04
Rgsu04
 
Rgsu04
Rgsu04Rgsu04
Rgsu04
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй это
 
Универсальный сигнатурный анализ кода на C#, Java, PHP
Универсальный сигнатурный анализ кода на C#, Java, PHPУниверсальный сигнатурный анализ кода на C#, Java, PHP
Универсальный сигнатурный анализ кода на C#, Java, PHP
 
Ф'Yii'лософия
Ф'Yii'лософияФ'Yii'лософия
Ф'Yii'лософия
 
О сложностях программирования, или C# нас не спасет?
О сложностях программирования, или C# нас не спасет?О сложностях программирования, или C# нас не спасет?
О сложностях программирования, или C# нас не спасет?
 
Как выглядит современный фронтенд
Как выглядит современный фронтендКак выглядит современный фронтенд
Как выглядит современный фронтенд
 
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кодаSECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
 
Parallel STL
Parallel STLParallel STL
Parallel STL
 
functional patterns - dotnetconf'11
functional patterns - dotnetconf'11functional patterns - dotnetconf'11
functional patterns - dotnetconf'11
 
Зачем обычному программисту знать языки, на которых почти никто не пишет. Але...
Зачем обычному программисту знать языки, на которых почти никто не пишет. Але...Зачем обычному программисту знать языки, на которых почти никто не пишет. Але...
Зачем обычному программисту знать языки, на которых почти никто не пишет. Але...
 
Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey Teplyakov
 
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
 
Лекция 7: Фибоначчиевы кучи (Fibonacci heaps)
Лекция 7: Фибоначчиевы кучи (Fibonacci heaps)Лекция 7: Фибоначчиевы кучи (Fibonacci heaps)
Лекция 7: Фибоначчиевы кучи (Fibonacci heaps)
 
20090720 hpc exercise1
20090720 hpc exercise120090720 hpc exercise1
20090720 hpc exercise1
 
Solit 2014, Минусы ООП на примере языка PHP, Соловей Василий
Solit 2014, Минусы ООП на примере языка PHP, Соловей ВасилийSolit 2014, Минусы ООП на примере языка PHP, Соловей Василий
Solit 2014, Минусы ООП на примере языка PHP, Соловей Василий
 
2. Операторы языка C#
2. Операторы языка C#2. Операторы языка C#
2. Операторы языка C#
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVM
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVM
 

Transpile it.pdf

  • 1. Трудности перевода переводим код между языками весело и задорно
  • 3. Что сегодня будет? Минутка самолюбования Общая информация про методы парсинга Пример из жизни: как я писал транспайлер из typescript в php
  • 4. АВТФ,2010 Вычислительные комплексы системы и сети Системная аналитика
  • 5.
  • 6.
  • 8. Из чего состоит ЯП? Токены: литералы,операторы,ключевые слова Лексический акцептор/анализатор Синтаксические конструкции: условные операторы, функции,классы Синтаксический акцептор/анализатор Семантика: смысл,который несет в себе код,выраженный в виде синтаксических конструкций ???
  • 9.
  • 10. Лексический анализатор 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 ] */ ] */
  • 11. Синтаксический анализатор 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' } } } } } } } }
  • 12. А что дальше? Преобразование AST Генерация кода по AST Оптимизации времени компиляции Виртуальная машина JIT ....
  • 13. 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> >
  • 14. // 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' } } } } } } } }
  • 15. // 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))
  • 16.
  • 18. Шо таки делать если на бэкенде у вас нет JS? Поставить nodejs ¯_(ツ)_/¯ Запихнуть рантайм v8 в этот ваш php/kphp GraalVM? А что если взять JS и сделать из него PHP?
  • 19. Допущения и ограничения Код на выходе не обязан соответствовать коду на входе. Для скорости можно ставить цель не поддерживать все возможные конструкции языка,т.е. ограничиться подмножеством языка. Околостатическая типизация 😨
  • 20. Что решили? Используем Typescript compiler API ...Не то что бы был какой-то иной выбор помимо typescript для языка реализации Инструменты для работы с AST у нас будут из коробки,что приятно Не пытаемся трансформировать AST,пишем сразу генератор кода
  • 21. Общая схема генерации кода yes no Start renderNode is terminal? Print as text Custom render logic
  • 22. Вернемся к примеру // 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)
  • 24. А что там с внедрением?
  • 25. Ресурсы Ахо,Ульман: Компиляторы Карпов: Основы построения трансляторов GNU Tools: Lex Bison JS Tools: Typescript compiler Espree