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
4.2k
ざっくり学ぶ言語のしくみ
itkrt2y
December 09, 2017
Tweet
Share
Featured
See All Featured
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.4k
Documentation Writing (for coders)
carmenintech
72
4.9k
The Invisible Side of Design
smashingmag
301
51k
Building an army of robots
kneath
306
45k
Site-Speed That Sticks
csswizardry
10
730
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
60k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
29
9.6k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
50
5.5k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
139
34k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
2.9k
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ͷ͘͠Έ
Ҏ্
ݴޠॲཧܥָ͍͔͠Β ΈΜͳΖ͏ʂʂ