Slide 1

Slide 1 text

Copyright © 2020 Present ANDPAD Inc. Modular semantic actions Yudai TAKADA @ydah 2024/06/25 LR Parser Night w/ Asakusa.rb

Slide 2

Slide 2 text

Copyright © 2020 Present ANDPAD Inc Yudai TAKADA ΫϦΤΠςΟϒεϖʔε ͜ͷൣғͷதͰσβΠϯ͍ͯͩ͘͠͞ About me @ydah RuboCop RSpec team Co-Founder of Kyobashi.rb Maintainer of committee Software Engineer at ANDPAD Committer of ruby/lrama

Slide 3

Slide 3 text

Copyright © 2024 Present ANDPAD Inc ANDPADとは 社内 現場 営業 / 監督 / 設計 事務 / 管理職 職人 / 業者 メーカー / 流通 (Ruby logo Copyright © 2006, Yukihiro Matsumoto) 現場の効率化から経営改善まで一元管理できる クラウド型建設プロジェクト管理サービス ANDPADのプロダクトを 支えている Ruby 施工管理 チャット 図面 引合粗利管理 検査 黒板 受発注 API 連携 3Dスキャン デジタル サイン機能 豆図AI キャプチャ機能 BIM ボード 資料承認 おうちノート

Slide 4

Slide 4 text

Copyright © 2020 Present ANDPAD Inc. Today’s Talk

Slide 5

Slide 5 text

Copyright © 2020 Present ANDPAD Inc. •文法規則に関連付けられたコードブロック •適用されたときに実行される •文法規則の後に `{}` (中括弧)で囲んで書く •C言語っぽいが独自の機能や変数が提供されている •例: `$$`, `$n` など Semantic actions

Slide 6

Slide 6 text

Copyright © 2020 Present ANDPAD Inc. •例えば、以下だと1つ目のsymbolと Semantic actionsの例 exp r : NUM | exp r '+' exp r { $$ = $1 + $3; } ;

Slide 7

Slide 7 text

Copyright © 2020 Present ANDPAD Inc. •例えば、以下だと1つ目のsymbolと3つ目のsymbolを Semantic actionsの例 exp r : NUM | exp r '+' exp r { $$ = $1 + $3; } ;

Slide 8

Slide 8 text

Copyright © 2020 Present ANDPAD Inc. •例えば、以下だと1つ目のsymbolと3つ目のsymbolを 合計したものを返り値にする Semantic actionsの例 exp r : NUM | exp r '+' exp r { $$ = $1 + $3; } ;

Slide 9

Slide 9 text

Copyright © 2020 Present ANDPAD Inc. なるほど!簡単!

Slide 10

Slide 10 text

Copyright © 2020 Present ANDPAD Inc. •簡単だと言ったな、あれは嘘だ 現実は残酷 | p r ima r y_value call_op ope r ation2 opt_pa r en_a r gs { bool has_a r gs = $4 ! = 0; if (NODE_EMPTY_ARGS_P($4)) $4 = 0; $$ = new_qcall(p, $2, $1, $3, $4, &@3, &@$); nd_set_line($$, @3.end_pos.lineno); / * % r ippe r : call!($ : 1, $ : 2, $ : 3) % * / if (has_a r gs) { / * % r ippe r : method_add_a r g!($:$, $ : 4) % * / } }

Slide 11

Slide 11 text

Copyright © 2020 Present ANDPAD Inc. •コメントかと思った?残念!ripperのコードでした! | p r ima r y_value call_op ope r ation2 opt_pa r en_a r gs { bool has_a r gs = $4 ! = 0; if (NODE_EMPTY_ARGS_P($4)) $4 = 0; $$ = new_qcall(p, $2, $1, $3, $4, &@3, &@$); nd_set_line($$, @3.end_pos.lineno); / * % r ippe r : call!($ : 1, $ : 2, $ : 3) % * / if (has_a r gs) { / * % r ippe r : method_add_a r g!($:$, $ : 4) % * / } } 現実は残酷

Slide 12

Slide 12 text

Copyright © 2020 Present ANDPAD Inc. •アクションの中に状態?? 現実… | keywo r d_ r et r y { if (!p - > ctxt.in_def i ned) { switch (p - > ctxt.in_ r escue) { case befo r e_ r escue: yye r r o r 1(&@1, "Invalid r et r y without r escue"); b r eak; case afte r _ r escue: / * ok * / b r eak; case afte r _else: yye r r o r 1(&@1, "Invalid r et r y afte r else"); b r eak; case afte r _ensu r e: yye r r o r 1(&@1, "Invalid r et r y afte r ensu r e"); b r eak; } } $$ = NEW_RETRY(&@$); / * % r ippe r : r et r y! % * / }

Slide 13

Slide 13 text

Copyright © 2020 Present ANDPAD Inc. •単純に返り値を組み立てるだけではない •ASTも作りたい •Ripperのロジックも普通にいる •意味解析もしてる Action͸ࢥ͍ͬͯΔΑΓ΋೉͍͠

Slide 14

Slide 14 text

Copyright © 2020 Present ANDPAD Inc. •こういう文法規則だけなら分かりやすい parse.y͕ͳͥ೉͍͠ͷ͔ʁ defs_head : k_def singleton dot_o r _colon def_name ;

Slide 15

Slide 15 text

Copyright © 2020 Present ANDPAD Inc. •ただまあこうなる parse.y͕ͳͥ೉͍͠ͷ͔ʁ defs_head : k_def singleton dot_o r _colon ɹɹɹɹɹ { SET_LEX_STATE(EXPR_FNAME); p - > ctxt.in_a r gdef = 1; } def_name { SET_LEX_STATE(EXPR_ENDFN|EXPR_LABEL); / * fo r ce fo r a r gs * / $$ = def_head_save(p, $k_def); $$ - > nd_mid = $def_name; $$ - > nd_def = NEW_DEFS($singleton, $def_name, 0, &@$); / * % r ippe r : [$:singleton, $:dot_o r _colon, $:def_name] % * / } ;

Slide 16

Slide 16 text

Copyright © 2020 Present ANDPAD Inc. • Actionのコードは何でもできる • だから、色んなことをしている • Actionのコードを共通化する術がない • 生成規則にはParameterizing Rulesがある • 生成規則は同じ構造だけどActionが異なる場合がある •Parameterizing Rulesとして構造化したいが出来ない parse.y͕೉͍͠ཧ༝ = Action?

Slide 17

Slide 17 text

Copyright © 2020 Present ANDPAD Inc. ┏━┷━┓ ┃ア p┃ ┃ク a┃ ┃シ r┃ ┃ョ s┃ ┃ン e┃ ┃が .┃ ┃な y┃ ┃く か┃ ┃な ら┃ ┃り  ┃ ┃ま  ┃ ┃す  ┃ ┃よ  ┃ ┃う  ┃ ┃に  ┃  ┗━━━☆彡 ΅͕ͨͪ͘ࢥ͏͜ͱ

Slide 18

Slide 18 text

Copyright © 2020 Present ANDPAD Inc. •Alessandro Warth, Patrick Dubroy and Tony Garnock-Jones “Modular semantic actions” 2016/11 https://dl.acm.org/doi/abs/10.1145/ 2989225.2989231 Modular semantic actions

Slide 19

Slide 19 text

Copyright © 2020 Present ANDPAD Inc. • >We introduce Ohm, a parser generator in which both grammars and their interpretations can be extended in safe and modular ways. >Unlike many similar tools, Ohm completely separates grammars and semantic actions, avoiding the problems that arise when these two concerns are mixed. Abstract

Slide 20

Slide 20 text

Copyright © 2020 Present ANDPAD Inc. • >We introduce Ohm, a parser generator in which both grammars and their interpretations can be extended in safe and modular ways. >Unlike many similar tools, Ohm completely separates grammars and semantic actions, avoiding the problems that arise when these two concerns are mixed. Abstract

Slide 21

Slide 21 text

Copyright © 2020 Present ANDPAD Inc. • https://github.com/ohmjs/ohm • JavaScript製のライブラリとDSLで構成される構文解析のため のtoolkit • PEG(Parsing expression grammar)に基づいている • 特徴は文法規則とSemantic Actionを完全に分離している Ohmʁ

Slide 22

Slide 22 text

Copyright © 2020 Present ANDPAD Inc. จ๏نଇͱSemantic ActionΛ׬શʹ෼཭͍ͯ͠Δʁ •文法規則の定義 const g r amma r = ohm.g r amma r (` A r ithmetic { AddExp = AddExp_plus | AddExp_minus | MulExp AddExp_plus = AddExp "+" MulExp AddExp_minus = AddExp "-" MulExp } `);

Slide 23

Slide 23 text

Copyright © 2020 Present ANDPAD Inc. จ๏نଇͱSemantic ActionΛ׬શʹ෼཭͍ͯ͠Δʁ •ActionTableに`eval` Operationを追加 const semantics = g r amma r .c r eateSemantics(); semantics.addOpe r ation(‘eval’, { AddExp_plus(a, _, b) { r etu r n a.eval() + b.eval(); }, AddExp_minus(a, _, b) { r etu r n a.eval() - b.eval(); } });

Slide 24

Slide 24 text

Copyright © 2020 Present ANDPAD Inc. จ๏نଇͱSemantic ActionΛ׬શʹ෼཭͍ͯ͠Δʁ •`eval` の定義をLHSごとに追加 const semantics = g r amma r .c r eateSemantics(); semantics.addOpe r ation(‘eval’, { AddExp_plus(a, _, b) { r etu r n a.eval() + b.eval(); }, AddExp_minus(a, _, b) { r etu r n a.eval() - b.eval(); } });

Slide 25

Slide 25 text

Copyright © 2020 Present ANDPAD Inc. [ semantics(g r amma r .match('1 + 2 - 3 + 4')).eval() = = 4, semantics(g r amma r .match('12345')).eval() = = 12345 ] = > A r r ay(2)[t r ue, t r ue] จ๏نଇͱSemantic ActionΛ׬શʹ෼཭͍ͯ͠Δʁ •以下のように実行することができる •grammar.match() でシンタックスチェック

Slide 26

Slide 26 text

Copyright © 2020 Present ANDPAD Inc. จ๏نଇͱSemantic ActionΛ׬શʹ෼཭͍ͯ͠Δʁ •以下のように実行することができる •grammar.match() でシンタックスチェック •semantics().eval() で ActionTable内のevalを実行 [ semantics(g r amma r .match('1 + 2 - 3 + 4')).eval() = = 4, semantics(g r amma r .match('12345')).eval() = = 12345 ] = > A r r ay(2)[t r ue, t r ue]

Slide 27

Slide 27 text

Copyright © 2020 Present ANDPAD Inc. Lramaʹಋೖͯ͠ΈΔ defs_head : k_def singleton dot_o r _colon ɹɹɹɹɹ { SET_LEX_STATE(EXPR_FNAME); p - > ctxt.in_a r gdef = 1; } def_name { SET_LEX_STATE(EXPR_ENDFN|EXPR_LABEL); / * fo r ce fo r a r gs * / $$ = def_head_save(p, $k_def); $$ - > nd_mid = $def_name; $$ - > nd_def = NEW_DEFS($singleton, $def_name, 0, &@$); / * % r ippe r : [$:singleton, $:dot_o r _colon, $:def_name] % * / } ; •Before

Slide 28

Slide 28 text

Copyright © 2020 Present ANDPAD Inc. Lramaʹಋೖͯ͠ΈΔ defs_head : k_def singleton dot_o r _colon def_name ; %action defs_head_dot_o r _colon: { SET_LEX_STATE(EXPR_FNAME); p - > ctxt.in_a r gdef = 1; } %action defs_head_def_name: { SET_LEX_STATE(EXPR_ENDFN|EXPR_LABEL); / * fo r ce fo r a r gs * / / * % r ippe r : [$:singleton, $:dot_o r _colon, $:def_name] % * / } •After

Slide 29

Slide 29 text

Copyright © 2020 Present ANDPAD Inc. ෼཭͸Մೳ͕ͩ •Actionを定義しているものとパススルーなActionである ものと判断が一目で分からない •生成規則名が内部的に割り振られるParameterizing Rulesとは相性が悪い •Midrule Actionがあるので生成規則と一対一にならない

Slide 30

Slide 30 text

Copyright © 2020 Present ANDPAD Inc. •parse.yが難しい理由の一つには複雑なActionが挙げられる •Actionと生成規則を分離するアプローチは現状のLramaに 当てはめるのは難しそう •とはいえ、Actionは削っていきたいし共通化する手段は欲 しいので引き続き模索していきたい Conclusion

Slide 31

Slide 31 text

Copyright © 2020 Present ANDPAD Inc. This information is confidential and was prepared by ANDPAD Inc. for the use of our client. It is not to be relied on by and 3rd party. Proprietary & Confidential ແஅసࡌɾແஅෳ੡ͷېࢭ • Lrama LALR (1) parser generator https://github.com/ruby/lrama • Alessandro Warth, Patrick Dubroy and Tony Garnock-Jones “Modular semantic actions” 2016/11 https://dl.acm.org/doi/abs/10.1145/2989225.2989231 • Ohm a library and language for building parsers, interpreters, compilers, etc. https:// github.com/ohmjs/ohm • Patrick Dubroy, Martin Kavalar, Dieter Komendera, Joshua Sierls and Gregor Koehler “Ohm: Parsing Made Easy” 2023/5/6 https://nextjournal.com/dubroy/ohm-parsing-made-easy • Syntax Reference | Ohm https://ohmjs.org/docs/syntax-reference References Confidential

Slide 32

Slide 32 text

Copyright © 2020 Present ANDPAD Inc. end