Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ざっくり学ぶ言語のしくみ
Search
itkrt2y
December 09, 2017
4
4k
ざっくり学ぶ言語のしくみ
itkrt2y
December 09, 2017
Tweet
Share
More Decks by itkrt2y
See All by itkrt2y
サーバーサイドエンジニアも知っておくべきフロントエンドの今
itkrt2y
55
120k
Featured
See All Featured
Put a Button on it: Removing Barriers to Going Fast.
kastner
58
3.4k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
26
1.3k
Web development in the modern age
philhawksworth
204
10k
A better future with KSS
kneath
235
17k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
354
29k
Automating Front-end Workflow
addyosmani
1365
200k
Agile that works and the tools we love
rasmusluckow
327
20k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
326
21k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
8.9k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
23
1.7k
Fashionably flexible responsive web design (full day workshop)
malarkey
401
65k
What's in a price? How to price your products and services
michaelherold
242
11k
Transcript
ͬ͘͟ΓֶͿݴޠͷ͘͠Έ Rails Developers Meetup 2017 2017/12/09
ࣗݾհ • ൘ୡʢ@itkrt2yʣ • λέϢʔɾΣϒגࣜձࣾ • Railsͷडୗձࣾ • ϑϧϦϞʔτɺϑϧϑϨοΫε •
ઈࢍ࠾༻தʂʂڵຯ͋ΔํޙͰΛ͔͚͍ͯͩ͘͞
ࠓͷ
ݴޠॲཧܥ
͜͜ΒΜͷ୯ޠ͕Θ͔Βͳ͍ਓ͚ ࣈ۟ղੳ, ߏจղੳ, ධՁ, ίϯύΠϧ, yacc, τʔΫϯ, நߏจʢASTʣ, Ripper
Α͋͘ΔݴޠॲཧܥͷྲྀΕ ʮͬ͘͟ΓʯͰ͢ͷͰɺࡉ͔͍શྗͰল͖·͢
ίʔυ
ίʔυ ࣈ۟ղੳ Lex
ίʔυ τʔΫϯྻ ࣈ۟ղੳ Lex
ίʔυ τʔΫϯྻ ߏจղੳ Parse ࣈ۟ղੳ Lex
ίʔυ τʔΫϯྻ ߏจղੳ Parse நߏจ ࣈ۟ղੳ Lex
ίʔυ τʔΫϯྻ ߏจղੳ Parse நߏจ ධՁ Evaluate ࣈ۟ղੳ Lex
ίʔυ τʔΫϯྻ ߏจղੳ Parse நߏจ ݁Ռ ධՁ Evaluate ࣈ۟ղੳ Lex
ίʔυ τʔΫϯྻ ߏจղੳ Parse நߏจ ݁Ռ ࣮ߦɾධՁ ίϯύΠϧ Compile ࣈ۟ղੳ
Lex ωΠςΟϒίʔυ όΠτίʔυ ͳͲ
ίʔυ τʔΫϯྻ ߏจղੳ Parse நߏจ ݁Ռ ࣮ߦɾධՁ ίϯύΠϧ Compile ධՁ
Evaluate ࣈ۟ղੳ Lex ωΠςΟϒίʔυ όΠτίʔυ ͳͲ
ίʔυ τʔΫϯྻ ߏจղੳ Parse நߏจ ݁Ռ ࣮ߦɾධՁ ίϯύΠϧ Compile ධՁ
Evaluate ࣈ۟ղੳ Lex ωΠςΟϒίʔυ όΠτίʔυ ͳͲ
ίʔυΛτʔΫϯʢίʔυͷ࠷খ୯Ґʣʹׂ͢Δ puts ( 2 ࣝผࢠ + ࠨׅހ puts (10
+ 2*3)/4 10 + * ۭന * 3 ) ӈׅހ ۭന / / 4 ۭന
# Structͷྻ࿈ྻͷྻͳͲɺΓํ৭ʑ [ [:identifier, "puts"], [:space, " "], [:lparen, "("],
[:int, "10"], [:space, " "], [:plus, "+"], [:space, " "], [:int, "2"], [:asterisk, "*"], [:int, "3"], [:rparen, ")"], [:slash, "/"], [:int, "4"] ] ίʔυ্Ͱ͜Μͳײ͡
ίʔυ τʔΫϯྻ ߏจղੳ Parse நߏจ ݁Ռ ࣮ߦɾධՁ ίϯύΠϧ Compile ධՁ
Evaluate ࣈ۟ղੳ Lex ωΠςΟϒίʔυ όΠτίʔυ ͳͲ
τʔΫϯྻ͔ΒநߏจΛ࡞Δ ident:puts lparen:( int:10 plus:+ space: space: space: int:2 asterisk:*
int:3 rparen:) slash:/ int:4 int:10 plus:+ int:2 asterisk:* int:3 ident:puts slash:/ int:4 <token>:<literal>
நߏจͱʁ • ߏͷσʔλߏ • AST (Abstract Syntax Tree) • ந
== ຊ࣭Λൈ͖ग़ͨ͠ͷ • ίϝϯτۭനͳͲɺ࣮ߦ্ෆཁͳใΛഉআ͠ඞཁ ͳใͷΈͰߏ͞ΕΔ
ident:puts lparen:( int:10 plus:+ space: space: space: int:2 asterisk:* int:3
rparen:) slash:/ int:4 int:10 plus:+ int:2 asterisk:* int:3 ident:puts slash:/ int:4 ࠓճͷྫͰͷͷ͕ASTʹͳ͍
int:10 plus:+ int:2 asterisk:* int:3 ident:puts slash:/ int:4 ͪͳΈʹׅހ͕ͳ͔ͬͨΒ puts
10 + 2 * 3 / 4 ߏจͷߏͰ࣮ߦॱং͕ දݱ͞Ε͍ͯΔ
ίʔυ τʔΫϯྻ ߏจղੳ Parse நߏจ ݁Ռ ࣮ߦɾධՁ ίϯύΠϧ Compile ධՁ
Evaluate ࣈ۟ղੳ Lex ωΠςΟϒίʔυ όΠτίʔυ ͳͲ
ίϯύΠϧ • ͋ΔݴޠΛଞͷݴޠʹ༁͢Δ͜ͱ • ྫɿ CιʔείʔυΛόΠφϦʹ༁͢Δ • େߴڃݴޠ͔Βڃݴޠͷ༁Λࢦ͢ • ಉਫ४ؒͰ༁ͨ͠ͳΒίϯύΠϧ͕ͩɺίϯύΠ
ϧͱ͍͏ݴ༿ʹʮߴڃݴޠ͔Βڃݴޠʯͷ༁ ͱ͍͏ҙຯ߹ؚ͍͕·ΕΔ͜ͱ͕ଟ͍
int:10 plus:+ int:2 asterisk:* int:3 ident:puts slash:/ int:4 ͜ͷॲཧΛԿ͔ ผͷݴޠʹஔ͖͑Δ
ίʔυ τʔΫϯྻ ߏจղੳ Parse நߏจ ݁Ռ ࣮ߦɾධՁ ίϯύΠϧ Compile ධՁ
Evaluate ࣈ۟ղੳ Lex ωΠςΟϒίʔυ όΠτίʔυ ͳͲ
ධՁ • ࣮ߦͯ͠ΛಘΔ͜ͱ • ୯ʹʮ࣮ߦʯͱݴΘͳ͍ͷɺࣜΛͲͷΑ͏ʹղऍ͠ ࣮ͯߦ͢Δ͔ͦͷݴޠʹΑΔͨΊ • ΠϯλϓϦλݴޠͳΒɺCͳͲͰॻ͔ΕͨΠϯλϓϦλ ͕ASTΛஞ࣮࣍ߦ͢Δͷ͕Ұൠత •
ͪΖΜɺํ๏ͦͷଞ৭ʑ͋Δ
நߏจΛධՁ͢ΔྲྀΕͷΠϝʔδ ʢίʔυʹ͢Δͱ࠶ؼָ͕͍͘͢͝͠ʣ
int:10 plus:+ int:2 asterisk:* int:3 ident:puts slash:/ int:4
int:10 plus:+ int:2 asterisk:* int:3 ident:puts slash:/ int:4
int:10 plus:+ int:2 asterisk:* int:3 ident:puts slash:/ int:4
int:10 plus:+ int:2 asterisk:* int:3 ident:puts slash:/ int:4
int:10 plus:+ int:2 asterisk:* int:3 ident:puts slash:/ int:4
int:10 plus:+ int:2 asterisk:* int:3 ident:puts slash:/ int:4
int:10 plus:+ int:2 asterisk:* int:3 ident:puts slash:/ int:4
int:10 plus:+ int:2 asterisk:* int:3 ident:puts slash:/ int:4
int:10 plus:+ int: 6 ident:puts slash:/ int:4
int:16 ident:puts slash:/ int:4
int:16 ident:puts slash:/ int:4
ident:puts int:4
4 puts 4ͷ݁Ռ͕දࣔ͞ΕΔ
ίʔυ τʔΫϯྻ ߏจղੳ Parse நߏจ ݁Ռ ࣮ߦɾධՁ ίϯύΠϧ Compile ධՁ
Evaluate ࣈ۟ղੳ Lex Ҏ্ɺͬ͘͟Γͨ͠ݴޠͷ͘͠ΈͰͨ͠ ωΠςΟϒίʔυ όΠτίʔυ ͳͲ
ͪΌΜͱษڧ͍ͨ͠ਓ Writing An Interpreter In Go͕Φεεϝ • ӳޠͷຊͰ͕͢ɺςετίʔυ͕͔ͬ͠Γͯ͠ΔͷͰίʔ υΛಡΊͳΜͱ͔ͳΓ·͢ •
A Tour of GoΛҰ௨Γཧղ͍ͯ͠Εେৎ • amazon.co.jpͰkindle൛ΛߪೖՄೳ • 2351ԁʢ2017/12/09࣌ʣ
ͬ͘͟ΓֶͿݴޠͷ͘͠Έ
ୈ2෦ ͬ͘͟ΓֶͿRubyͷ͘͠Έ
ίʔυ τʔΫϯྻ ߏจղੳ Parse நߏจ ݁Ռ ωΠςΟϒίʔυ όΠτίʔυ ͳͲ ࣮ߦɾධՁ
ίϯύΠϧ Compile ධՁ Evaluate ࣈ۟ղੳ Lex Ұൠతͳϑϩʔ
Ruby 1.8·Ͱ ίʔυ ධՁ ࣈ۟ղੳ + ߏจղੳ நߏจ ݁Ռ
ίʔυ ධՁ ࣈ۟ղੳ + ߏจղੳ நߏจ ݁Ռ Ruby 1.9Ҏ߱ :"37
໋ྩྻ ίϯύΠϧ YARV
ίʔυ ධՁ ࣈ۟ղੳ + ߏจղੳ நߏจ ݁Ռ Ruby 3? :"37
໋ྩྻ ίϯύΠϧ ωΠςΟϒ ίʔυ ίϯύΠϧ ࣮ߦ
ίʔυ ධՁ ࣈ۟ղੳ + ߏจղੳ நߏจ ݁Ռ :"37 ໋ྩྻ ίϯύΠϧ
parse.y ίʔυ நߏจ
parse.c parse.y bison ίʔυ நߏจ
parse.c parse.y bison def/keywords ίʔυ நߏจ
parse.c + lex.c parse.y bison def/keywords gperf ίʔυ நߏจ
parse.c parse.y bison def/keywords gperf ίʔυ நߏจ ΑΓਖ਼֬ʹݴ͏ͱ parse.o y.tab.c
mv lex.c cc Rubyιʔείʔυશղઆ ୈ10ষ ύʔαΑΓ cpp
parse.c + lex.c parse.y bison def/keywords gperf ίʔυ நߏจ
parse.y • ߏจఆٛɾτʔΫϯఆٛϑΝΠϧ • ͜ͷϑΝΠϧΛݩʹɺbisonͰߏจղੳثΛ࡞Δ • io.cʹ͍࣍Ͱ2൪ʹߦͷଟ͍ϑΝΠϧʢͷͣʣ • 12000ߦӽ͑ʂʂʢ2017/12/09࣌ʣ •
७ਮͳߏจఆٛͷΈΛݟ͍ͨ߹sample/exyacc.rb͕ศར • `ruby sample/exyacc.rb parse.y`
parse.c + lex.c parse.y bison def/keywords gperf ίʔυ நߏจ
bison (yacc) • ύʔαδΣωϨʔλ • yaccͷ্Ґޓ • yacc == yet
another compiler compiler • compiler compiler == compiler generator • Ͱyaccparser generator • Backus-Naur FormʢBNF: όοΧεφΞه๏ʣ • ͜͏͍͏ͷ !
parse.c + lex.c parse.y bison def/keywords gperf ίʔυ நߏจ
def/keywords • ༧ޠఆٛϑΝΠϧ • ͜ͷϑΝΠϧΛݩʹgperfΛͬͯlex.cΛੜ͠ɺͦΕΛ parse.cͰinclude͢Δ • gperf == શϋογϡؔੜث
ࣈ۟ղੳɾߏจղੳ݁ՌΛݟΔ
Ripper • RubyΈࠐΈͷύʔαϥΠϒϥϦ require 'ripper' code = 'puts "Hello World!"'
# ࣈ۟ղੳ Ripper.lex(code) # ߏจղੳ Ripper.sexp(code) # sexp == symbolic expression (Sࣜ)
ίʔυ ධՁ ࣈ۟ղੳ + ߏจղੳ நߏจ ݁Ռ :"37 ໋ྩྻ ίϯύΠϧ
நߏจ :"37 ໋ྩྻ compile.c
code = 'puts "Hello World!"' RubyVM::InstructionSequence.compile(code).disasm ίϯύΠϧ݁ՌΛݟΔ 1. --dump=insns ΦϓγϣϯΛ͚࣮ͭͯߦ
2. ίʔυͰίϯύΠϧͯ͠ٯΞηϯϒϧ͢Δ $ ruby --dump=insns sample.rb
puts (10 + 2*3)/4 == disasm: #<ISeq:<main>@sample.rb>===================================== 0000 trace 1
( 1) 0002 putself 0003 putobject 10 0005 putobject 2 0007 putobject 3 0009 opt_mult <callinfo!mid:*, argc:1, ARGS_SIMPLE>, <callcache> 0012 opt_plus <callinfo!mid:+, argc:1, ARGS_SIMPLE>, <callcache> 0015 putobject 4 0017 opt_div <callinfo!mid:/, argc:1, ARGS_SIMPLE>, <callcache> 0020 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>, <callcache> 0023 leave
ίʔυ ධՁ ࣈ۟ղੳ + ߏจղੳ நߏจ ݁Ռ :"37 ໋ྩྻ ίϯύΠϧ
݁Ռ :"37 ໋ྩྻ eval.c, insns.defͳͲ
YARVͷධՁͷྲྀΕ
0000 trace 0002 putself 0003 putobject 10 0005 putobject 2
0007 putobject 3 0009 opt_mult 0012 opt_plus 0015 putobject 4 0017 opt_div 0020 opt_send_without_block mid:puts 0023 leave YARV໋ྩྻ YARVͷ ෦ελοΫ
0000 trace 0002 putself 0003 putobject 10 0005 putobject 2
0007 putobject 3 0009 opt_mult 0012 opt_plus 0015 putobject 4 0017 opt_div 0020 opt_send_without_block mid:puts 0023 leave YARV໋ྩྻ YARVͷ ෦ελοΫ
0000 trace 0002 putself 0003 putobject 10 0005 putobject 2
0007 putobject 3 0009 opt_mult 0012 opt_plus 0015 putobject 4 0017 opt_div 0020 opt_send_without_block mid:puts 0023 leave TFMG YARV໋ྩྻ YARVͷ ෦ελοΫ
0000 trace 0002 putself 0003 putobject 10 0005 putobject 2
0007 putobject 3 0009 opt_mult 0012 opt_plus 0015 putobject 4 0017 opt_div 0020 opt_send_without_block mid:puts 0023 leave TFMG YARV໋ྩྻ YARVͷ ෦ελοΫ
0000 trace 0002 putself 0003 putobject 10 0005 putobject 2
0007 putobject 3 0009 opt_mult 0012 opt_plus 0015 putobject 4 0017 opt_div 0020 opt_send_without_block mid:puts 0023 leave TFMG YARV໋ྩྻ YARVͷ ෦ελοΫ
0000 trace 0002 putself 0003 putobject 10 0005 putobject 2
0007 putobject 3 0009 opt_mult 0012 opt_plus 0015 putobject 4 0017 opt_div 0020 opt_send_without_block mid:puts 0023 leave TFMG YARV໋ྩྻ YARVͷ ෦ελοΫ
0000 trace 0002 putself 0003 putobject 10 0005 putobject 2
0007 putobject 3 0009 opt_mult 0012 opt_plus 0015 putobject 4 0017 opt_div 0020 opt_send_without_block mid:puts 0023 leave TFMG YARV໋ྩྻ YARVͷ ෦ελοΫ
0000 trace 0002 putself 0003 putobject 10 0005 putobject 2
0007 putobject 3 0009 opt_mult 0012 opt_plus 0015 putobject 4 0017 opt_div 0020 opt_send_without_block mid:puts 0023 leave TFMG YARV໋ྩྻ YARVͷ ෦ελοΫ
0000 trace 0002 putself 0003 putobject 10 0005 putobject 2
0007 putobject 3 0009 opt_mult 0012 opt_plus 0015 putobject 4 0017 opt_div 0020 opt_send_without_block mid:puts 0023 leave TFMG YARV໋ྩྻ YARVͷ ෦ελοΫ
0000 trace 0002 putself 0003 putobject 10 0005 putobject 2
0007 putobject 3 0009 opt_mult 0012 opt_plus 0015 putobject 4 0017 opt_div 0020 opt_send_without_block mid:puts 0023 leave TFMG YARV໋ྩྻ YARVͷ ෦ελοΫ
0000 trace 0002 putself 0003 putobject 10 0005 putobject 2
0007 putobject 3 0009 opt_mult 0012 opt_plus 0015 putobject 4 0017 opt_div 0020 opt_send_without_block mid:puts 0023 leave OJM YARV໋ྩྻ YARVͷ ෦ελοΫ
ৄ͘͠ʰRubyͷ͘͠ΈʱΛ ಡΜͰ͍ͩ͘͞
ͦͷଞɺͬͱΓ͍ͨਓʹΦεεϝͷຊɾαΠτ • Rubyιʔείʔυશղઆ • https://docs.ruby-lang.org/en/2.4.0/ extension_ja_rdoc.html • https://github.com/ko1/rubyhackchallenge
ͬ͘͟ΓֶͿRubyͷ͘͠Έ
Ҏ্
ݴޠॲཧܥָ͍͔͠Β ΈΜͳΖ͏ʂʂ