Slide 1

Slide 1 text

GoͰ࣮૷͢Δ
 ܰྔϚʔΫΞοϓݴޠ
 ύʔαʔ id:aereal @ builderscon tokyo 2017

Slide 2

Slide 2 text

࿩͢͜ͱ • ܰྔϚʔΫΞοϓݴޠͱ͸ͯͳه๏ʹ͍ͭͯ • ςΩετॲཧͱύʔαʔδΣωϨʔλʔͷඞཁੑ • Go/goyaccʹΑΔ͸ͯͳه๏ύʔαʔͷ঺հ • goyaccͷԠ༻஌ࣝ

Slide 3

Slide 3 text

ࣗݾ঺հ • id:aereal • GitHub: aereal • גࣜձࣾ͸ͯͳ
 ΞϓϦέʔγϣϯΤϯδχΞ

Slide 4

Slide 4 text

⚠͓͜ͱΘΓ⚠ • αʔϏεΛ৮͍ͬͯͯײͨ͡
 ݸਓతͳ՝୊ҙࣝʹجͮ͘ϓϥΠϕʔτϫʔΫͰ͢ • αʔϏεʹ࠾༻͞ΕΔ͔͸ෆ໌

Slide 5

Slide 5 text

ࢀߟ৘ใ • http://b.hatena.ne.jp/aereal/2017gokyoto/ • ͸ͯͳϒοΫϚʔΫͰλάΛ෇͚ͯϒΫϚ͍ͯ͠·͢

Slide 6

Slide 6 text

ܰྔϚʔΫΞοϓݴޠͱ
 ͸ͯͳه๏

Slide 7

Slide 7 text

ܰྔϚʔΫΞοϓݴޠͱ͸ • LML = Lightweight Markup Language • HTML΍XMLͱϓϨʔϯςΩετͷதؒʹ͋Δ • Markdown, Textile, ͸ͯͳه๏, etc.

Slide 8

Slide 8 text

ܰྔϚʔΫΞοϓݴޠͱ͸ • LML = Lightweight Markup Language • HTML΍XMLͱϓϨʔϯςΩετͷதؒʹ͋Δ • Markdown, Textile, ͸ͯͳه๏, etc.

Slide 9

Slide 9 text

͸ͯͳه๏ͱ͸ • ͸ͯͳ͕ఏڙ͢Δ͍͔ͭ͘ͷαʔϏεͰ࢖͑ΔLML • ͸ͯͳϒϩάɺ͸ͯͳμΠΞϦʔɺetc. • HTMLʹม׵͞ΕΔศརͳه๏ • org-modeͱͪΐͬͱࣅ͍ͯΔจ๏

Slide 10

Slide 10 text

* ݟग़͠1 ** ݟग़͠2 [http://127.0.0.1/:title=΅͘ͷIPͰ͢] - Ruby - Perl - Go + ى + ঝ + స + ݁

Slide 11

Slide 11 text

ݟग़͠1

ݟग़͠2

΅͘ͷIPͰ͢

  • Ruby
  • Perl
  • Go
  1. ى
  2. ݁

Slide 12

Slide 12 text

࣮૷͍Ζ͍Ζ • ͸ͯͳϒϩάɺ͸ͯͳμΠΞϦʔɺ͸ͯͳάϧʔϓ • Text-Hatena (CPAN) • Text-Xatena (CPAN) • chris4403/WikiTextConverter • motemen/pandoc

Slide 13

Slide 13 text

࣮૷͍Ζ͍Ζ • ࢓༷ ≈ ࣮૷ • ࣮૷͕͍Ζ͍Ζ͋Δ • ͭ·Γ • ࣮૷ͷ਺͚ͩ࢓༷͕ଘࡏ͢Δ • ࢓༷Λ஌Δʹ͸Perlͱਖ਼نදݱΛಡΈղ͘ඞཁ͕͋Δ

Slide 14

Slide 14 text

खࠒͳ࣮૷͕ແͯ͘ࠔΔ • PerlҎ֎Ͱॻ͔ΕͨΞϓϦέʔγϣϯͰ
 ͸ͯͳه๏Λ࢖͑ΔΑ͏ʹ͍ͨ͠ɺ͚Ͳ…… • Perlͷ֦ுਖ਼نදݱΛۦ࢖͍ͯ͠ΔͷͰҠ২΋େม • HTMLม׵·Ͱ΍Δύʔαʔ͕ଟ͍

Slide 15

Slide 15 text

ϙʔλϏϦςΟ • ϒϥ΢βͰϥΠϒϓϨϏϡʔͱ͔͍ͨ͠͡ΌΜ • ೖྗʹର͢Δग़ྗ (AST) ͚ͩΛܾΊ͍ͨ • Perl΍Go΍Scala, JavaScriptͦͷଞͰॻ͖͍ͨ

Slide 16

Slide 16 text

HTMLม׵·Ͱ΍Γͨ͘ͳ͍ • ଟ͘ͷύʔαʔ࣮૷͕HTMLม׵·Ͱߦ͏ • ҰํɺೖྗʹͲΕ͘Β͍HTMLΛڐՄ͢Δ͔͸
 αʔϏεຖ (!= ύʔαʔ࣮૷ຖ) ʹҟͳΔ • → ύʔαʔͱHTMLม׵Λ෼཭͍ͨ͠

Slide 17

Slide 17 text

͜Μͳ͸ͯͳه๏ύʔαʔ͕ ΄͍͠ • ϦϑΝϨϯεͨΓ͏Δૉ๿ͳ࣮૷ • = ਖ਼نදݱͰͳΜͱ͔͠Α͏ͱ͍͗ͯ͢͠ͳ͍ • ύʔε݁Ռ͕HTMLͰ͸ͳ͘தؒදݱ͕ಘΒΕΔ

Slide 18

Slide 18 text

ࡾߦͰ·ͱΊΔͱ • AST͘Ε!!!

Slide 19

Slide 19 text

࣍ճ༧ࠂ • ಛఆͷݴޠʹґଘ͠ͳ͍
 ྑ͍͔Μ͡ͷςΩετॲཧάοζ͸ͳ͍΋ͷ͔ • ͨͩ͠ (֦ு) ਖ਼نදݱҎ֎ • Αͦ͞͏ͳςΩετॲཧٕज़Λ୳͠ʹ͍͖·͢

Slide 20

Slide 20 text

ςΩετॲཧͱ
 ύʔαʔδΣωϨʔλʔ

Slide 21

Slide 21 text

ςΩετॲཧͻͱΊ͙Γ • ςΩετॲཧͷςΫχοΫΛ͍Ζ͍Ζ঺հ • έʔεʹΑͬͯ͸ύʔαʔΛॻ͘·Ͱ΋ͳ͔ͬͨΓ͢Δ

Slide 22

Slide 22 text

τʔΫϯͷग़ݱҐஔ "id:aereal".substring(3) // => "aereal"

Slide 23

Slide 23 text

τʔΫϯͷग़ݱҐஔ • τʔΫϯͷग़ݱҐஔ͕ݻఆ௕ͳΒ͜Ε͘Β͍Ͱ΋ • Մม௕ͩͱഁ୼͢Δ • ͓ͦͯ͠Αͦͷจ๏͸Մม௕ͷτʔΫϯ͹͔Γ

Slide 24

Slide 24 text

ਖ਼نදݱ /id:(.+)/.match("id:aereal")[1] // => "aereal"

Slide 25

Slide 25 text

ਖ਼نදݱ • ׅހͷඇରԠ͸ݕग़Ͱ͖ͳ͍ • (POSIXͷਖ਼نදݱͰ͸ෆՄɺ
 Perlͷ֦ுਖ਼نදݱͰ͸Ͱ͖ͨ͸ͣ) • Ұຊ௼Γ͕Ͱ͖ͳ͔ͬͨΒɺ
 ޙड़ͷঢ়ଶ؅ཧΛߦ͏ඞཁ͕͋Δ

Slide 26

Slide 26 text

ঢ়ଶભҠΛ؅ཧ var isInIdNotation = false; while (1) { if (isInIdNotation) { var name = readText(); // => "aereal" } else { switch (readChar()) { case ':': isInIdNotation = true; default: // ... } } }

Slide 27

Slide 27 text

ঢ়ଶભҠΛ؅ཧ var isInIdNotation = false; var isInHeading = false; var isInUnorderedList = false; var isInOrderedList = false; while (1) { if (isInIdNotation) if (isInHeading) if (isInUnorderedList) if (isInOrderedList) }

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

• ͲΕ΋จ๏Λ၆ᛌͮ͠Β͍ • ϞδϡʔϧԽ͕೉͍͠ • → খ͍͞෦඼ΛੵΈ্͍͛ͯ͘ελΠϧͰ࡞ΕͨΒ……

Slide 30

Slide 30 text

ͦ͜Ͱyacc • ύʔαʔδΣωϨʔλʔͷ1ͭ • BNFʹࣅͨߏจنଇ͔ΒύʔαʔΛੜ੒͢Δ • ෳ਺ͷنଇΛ૊Έ߹Θͤͯ1ͭͷنଇΛ࡞Γ্͛Δ • ίʔϧόοΫελΠϧͰ
 نଇΛϓϩάϥϜʹม׵͢Δ (ؐݩɺreduce)

Slide 31

Slide 31 text

https://tools.ietf.org/html/rfc7230 HTTP-Message = start-line *( header-field CRLF) CRLF [ message-body] start-line = request-line / status-line

Slide 32

Slide 32 text

yacc • BNFͱ͍͏ந৅తͳํ๏Ͱطड़Ͱ͖Δͷ͕Α͍ • ݴޠ಺DSLʹରͯ͠ϙʔλϏϦςΟͰ༏Δ • ϨΩαʔ (ࣈ۟ղੳث) ͸ผ్࣮૷͢Δඞཁ͕͋Δ • ߏจنଇͷίʔϧόοΫ෦͕
 ΤσΟλͰϋΠϥΠτ͞Εͳ͍ (ͳʹ͔͍͍ํ๏͋Γͦ͏)

Slide 33

Slide 33 text

࣍ճ༧ࠂ • yaccΑͦ͞͏ͱ͍͏͜ͱ͕Θ͔ͬͨ • GoͱyaccΛ૊Έ߹ΘͤΒΕΔͷ͔ • ͸ͨͯ͠͸ͯͳه๏ύʔαʔΛ࡞Δ͜ͱ͕Ͱ͖Δͷ͔

Slide 34

Slide 34 text

https://git.io/v7gcD github.com/aereal/gohn

Slide 35

Slide 35 text

gohn • Written in Go w/goyacc • pronounce as `gone` • ओཁͳه๏͸࣮૷ࡁΈ

Slide 36

Slide 36 text

gohnͷσβΠϯ • ඪ४ೖྗ͔Β͸ͯͳه๏Λड͚औΓɺ • ඪ४ग़ྗʹASTΛJSONʹγϦΞϥΠζͯ͠ग़ྗ͢Δ • → HTML΁ͷม׵͸ผ్࣮૷͢Δ • ͱͯ΋UNIXత

Slide 37

Slide 37 text

AST • JSONʹγϦΞϥΠζ • JSON schemaΛެ։͍ͯ͠Δ • εΩʔϚ͔ΒHTMLม׵ثΛࣗಈੜ੒͢Δ͜ͱ΋Ͱ͖ͦ͏ • https://github.com/aereal/gohn/blob/master/schema.json

Slide 38

Slide 38 text

Goͱyacc • goyaccͱ͍͏πʔϧ͕͋Δ • go get golang.org/x/tools/cmd/goyacc • ΞΫγϣϯΛGoͰॻ͚Δ

Slide 39

Slide 39 text

Goͱࣈ۟ղੳ • ࣈ۟ղੳ = ಡΜͩจࣈ͕ͲΜͳҙຯΛ࣋ͭͷ͔ฦ͢ • text/scannerͱ͍͏ඪ४ύοέʔδ͕ศར • ڍಈΛΧελϚΠζͰ͖Δ • τʔΫϯΛফඅͨ͠࠷ޙͷҐஔΛه࿥ͯ͘͠ΕΔͷͰ
 Τϥʔϝοηʔδͷߏஙָ͕

Slide 40

Slide 40 text

σϞ

Slide 41

Slide 41 text

Ԡ༻ฤ

Slide 42

Slide 42 text

HTTPه๏ [http://example.com/] # 
 # http://example.com/ # [http://127.0.0.1/:title=΅͘ͷIP] # 
 # ΅͘ͷIP #

Slide 43

Slide 43 text

HTTPه๏ • ΞϯΧʔϦϯΫʹม׵͞ΕΔه๏ • ຤ඌʹల։࣌ͷΦϓγϣϯΛ `:` ʹଓ͚ͯطड़Ͱ͖Δ • `:` ͸URLͷҰ෦ʹݱΕΔ͜ͱ͕͋Δ • → ࣍ͷ1จࣈΛಡΉ͚ͩͰ͸:titleͷ։͔࢝൑அͰ͖ͳ͍

Slide 44

Slide 44 text

࠷ॳʹݱΕΔ `:` ͸εΩʔϜ෦ͱݟͳͯ͠ແࢹ͢Δ͜ͱʹ if !l.seenColon { l.seenColon = true return false // maybe part of URL } else { return true } https://github.com/aereal/gohn/blob/master/parser/ lex.go#L100

Slide 45

Slide 45 text

࠶ؼతͳϧʔϧ • N > 1ͷࢠنଇ͔ΒͳΔنଇͷॻ͖ํ • appendͷॱ൪͚ͩؒҧ͑ͳ͍Α͏ʹ

Slide 46

Slide 46 text

http_options: http_option { $$ = []string{$1} } | http_option http_options { options := $2 $$ = append([]string{$1}, options...) }

Slide 47

Slide 47 text

ςετ • Table-driven tests͕Φεεϝ • https://github.com/golang/go/wiki/TableDrivenTests • lexerΛؚΉparserͷػೳςετ͚ͩͰे෼ͩͱࢥ͏ • https://github.com/aereal/gohn/blob/master/parser/ parser_test.go#L17

Slide 48

Slide 48 text

σόοά • tokenͷࣝผࢠ (int) ͔Β໊લ (string) Λ
 ٯҾ͖͢ΔϝιουΛఆ͓ٛͯ͘͠ͱศར • print͢ΔʹͤΑσόοΨΛ࢖͏ʹͤΑ • https://github.com/aereal/gohn/blob/master/parser/ lex.go#L29

Slide 49

Slide 49 text

·ͱΊ

Slide 50

Slide 50 text

Go/goyacc͸ศར • Go͸ෳࡶͳCLIΛϙʔλϒϧʹ࡞Δͷʹ޲͍͍ͯΔ • goyacc (yacc) ͸ෳࡶͳจ๏ͷύʔαʔʹ޲͍͍ͯΔ

Slide 51

Slide 51 text

ܰྔϚʔΫΞοϓݴޠ͸ ೉͍͠ • ਓؒʹͱͬͯͷಡΈॻ͖͠΍͢͞ͱ
 ػցʹͱͬͯͷಡΈॻ͖͠΍͢͞͸ҟͳΔ • ݫ֨ͳจ๏نଇʹैΘͤΔύʔαʔΑΓ
 ޡΓగਖ਼ͯ͘͠ΕΔ΄͏͕࣮༻తͳͷͰ͸?

Slide 52

Slide 52 text

ύʔαʔ࡞Γ͸ָ͍͠ • Ͱ͖Δ͜ͱɺ΍Γ͍ͨ͜ͱɺؔ৺ͷ͋Δ͜ͱ͕
 ͏·͘όϥϯε͞Εͨ໨ඪ • WebͱςΩετॲཧ • খ͞ͳ໨ඪΛগͣͭ͠ੵΈॏͶ͍͚ͯΔ • ʮࠓ೔͸Ϧετه๏ͷ࣮૷͕Ͱ͖ͨͧʯ

Slide 53

Slide 53 text

ڵຯΛ࣋ͬͯ͘Εͨਓ΁ • ·ͣ͸JSONͷύʔαʔΛॻ͍ͯΈΔͱΑͦ͞͏ • RFC, relaxed JSON, etc. ʹൃలͤͯ͞ΈΔ • ࣍͸ࣈ۟ղੳثΛखॻ͖ͯ͠ΈΔ • ࣍͸ߏจղੳث΋खॻ͖ͯ͠ΈΔ

Slide 54

Slide 54 text

׬