僕が構文解析にこんなにも時間をかけてしまった理由...

67
構文解析こんなにも時間かけてしまった理由 会津大学 学部三年 / Eyes, JAPAN Co. Ltd. 伊藤勇希 / @publmag1 / acomagu 170722 Aizu.golang

Upload: yuki-ito

Post on 28-Jan-2018

211 views

Category:

Engineering


1 download

TRANSCRIPT

Page 1: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

僕が構文解析に

こんなにも時間を

かけてしまった理由会津大学 学部三年 / Eyes, JAPAN Co. Ltd.

伊藤勇希 / @publmag1 / acomagu170722 Aizu.golang

Page 2: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

自己紹介

- 伊藤勇希

- 福島県伊達市出身

- 会津大学学部3年- Eyes, JAPAN Co. Ltd.

Page 3: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

自己紹介

- 好きな言語:- Golang- Fish- 合唱

Page 4: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 5: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 6: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

自己紹介

- 好きなエディタ

- (Neo)Vim

Page 7: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

はじめに

Page 8: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

Welcome To Aizu!!!!

Page 9: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

ところで

Page 10: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

gometalinter つかってますか?

Page 11: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

gometalinter 最高くないですか?

Page 12: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

そんな僕が

Page 13: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

Fish にもLinterが欲しくて

Page 14: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

孤軍奮闘する切ない物語...

Page 15: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

僕が構文解析に

こんなにも時間を

かけてしまった理由

会津大学 学部三年 / Eyes, JAPAN Co. Ltd.伊藤勇希 / @publmag1 / acomagu

170722 Aizu.golang

〜Yacc / Bison におけるノウハウ集〜

Page 16: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

時は遡って6/22

Page 17: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 18: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

Lintツールの作成開始

Page 19: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 20: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

① 字句解析器と構文解析器の違いがわからない

Page 21: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

② %unionが全く理解できない

Page 22: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

%union とは

Page 23: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 24: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

構文解析中にずっと破棄されず使いまわされる

構造体のこと

Page 25: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

③ go tool yaccコマンドがない

Page 26: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

go tool yacc コマンドはgoyaccパッケージに移動しました!!!

(Since Go 1.8)

Page 27: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 28: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

④ セミコロンの省略はどうするか?

Page 29: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

\n と ; の2つがデリミタとして使える

Page 30: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

\n と ; の2つがデリミタとして使える

Page 31: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

空行はどうする?

Page 32: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 33: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

;\n+ をEOSに設定

Page 34: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 35: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

IF は 文? 式?

Page 36: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

最終的にこう定義した

- Statement: パイプ可能

- Expression: パイプ不可能

Page 37: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

- Statement: パイプ可能

- Expression: パイプ不可能

- > IF_STMT

最終的にこう定義した

Page 38: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 39: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

構文解析器にスペースを渡すか?

Page 40: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

なぜこんな話が出るのか?- スペースを構文解析器に渡すメリット

- クオーテーション内の変数と外の変数を統一

的に字句解析器がパースできる

- aa”bb”cc と aa “bb” cc の区別

Page 41: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

しかし

字句解析器が状態を持たなければならなく

なる (e.g. クオーテーション中? 外?)

なぜこんな話が出るのか?

Page 42: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

結論

悩んだ末、スペースを渡すことに

Page 43: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

しかし...

Page 44: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 45: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 46: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 47: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

Yacc(bison)は闇

- 複雑なことをしようとするとすぐにデバッグが困難

になる

- y.output(Yaccが出力するオートマトンの状態遷

移リスト)をコンフリクトする部分から3つ以上遡ら

なければならない状態くらいになるともう無理

- Wikipediaにも「経験上のノウハウ」のリストがあ

Page 48: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

Yaccに立ち向かうための武器

- bison -v

Page 49: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

というわけで...

Page 50: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 51: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

結論

悩んだ末、スペースを渡すことに

スペースを渡さずに字句解析側で頑張るこ

とに...

Page 52: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

しかししかし...

Page 53: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 54: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

問題

abc (ls) と abc(ls) がどちらも

IDENT ‘(‘ IDENT ‘)’ になってしまう!

Page 55: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 56: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 57: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 58: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

つまり

- abc( -> STRS_AND_LEFT_PAREN

- )def -> RIGHT_PAREN_AND_STRS

- )ghi(

-> RIGHT_PAREN_AND_STRS_AND_LEFT_PAREN

Page 59: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 60: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 61: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 62: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜
Page 63: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

ここで彼の言葉は終わっている...

Page 64: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

まとめ

- Yaccは闇

- 字句解析器と構文解析器でうまーくラインを引くノウハウが

必要

- デバッグの方法を知っておく

- ドキュメントが極端に少ないが、公式に目を通せば仕組み

は理解できる

- 静的解析は書き始める前にきっちり役割分担と要素を決める

べき

Page 65: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

まとめ

- go/ast、go/parser、go/tokenは読むべき

- mattnさんのstreeemの実装も無茶苦茶参考にな

- tenntennさんのgoyacc入門も穴が開くほど読ん

Page 66: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

Lintはすぐ! 完成させます!

Page 67: 僕が構文解析にこんなにも時間をかけてしまった理由 〜Yacc/Bisonにおけるノウハウ〜

Thanks!!!