Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Modular semantic actions

Modular semantic actions

Yudai Takada @ydah_
2024 年 6 月 25 日
After RubyKaigi 2024 LR Parser Night w/ Asakusa.rb

ANDPAD inc

June 27, 2024
Tweet

More Decks by ANDPAD inc

Other Decks in Programming

Transcript

  1. Copyright © 2020 Present ANDPAD Inc. Modular semantic actions Yudai

    TAKADA @ydah 2024/06/25 LR Parser Night w/ Asakusa.rb
  2. 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
  3. Copyright © 2024 Present ANDPAD Inc ANDPADとは 社内 現場 営業

    / 監督 / 設計 事務 / 管理職 職人 / 業者 メーカー / 流通 (Ruby logo Copyright © 2006, Yukihiro Matsumoto) 現場の効率化から経営改善まで一元管理できる クラウド型建設プロジェクト管理サービス ANDPADのプロダクトを 支えている Ruby 施工管理 チャット 図面 引合粗利管理 検査 黒板 受発注 API 連携 3Dスキャン デジタル サイン機能 豆図AI キャプチャ機能 BIM ボード 資料承認 おうちノート
  4. Copyright © 2020 Present ANDPAD Inc. •文法規則に関連付けられたコードブロック •適用されたときに実行される •文法規則の後に `{}`

    (中括弧)で囲んで書く •C言語っぽいが独自の機能や変数が提供されている •例: `$$`, `$n` など Semantic actions
  5. 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) % * / } }
  6. 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) % * / } } 現実は残酷
  7. 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! % * / }
  8. 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] % * / } ;
  9. Copyright © 2020 Present ANDPAD Inc. • Actionのコードは何でもできる • だから、色んなことをしている

    • Actionのコードを共通化する術がない • 生成規則にはParameterizing Rulesがある • 生成規則は同じ構造だけどActionが異なる場合がある •Parameterizing Rulesとして構造化したいが出来ない parse.y͕೉͍͠ཧ༝ = Action?
  10. Copyright © 2020 Present ANDPAD Inc. ┏━┷━┓ ┃ア p┃ ┃ク a┃ ┃シ r┃

    ┃ョ s┃ ┃ン e┃ ┃が .┃ ┃な y┃ ┃く か┃ ┃な ら┃ ┃り  ┃ ┃ま  ┃ ┃す  ┃ ┃よ  ┃ ┃う  ┃ ┃に  ┃  ┗━━━☆彡 ΅͕ͨͪ͘ࢥ͏͜ͱ
  11. 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
  12. 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
  13. 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
  14. Copyright © 2020 Present ANDPAD Inc. • https://github.com/ohmjs/ohm • JavaScript製のライブラリとDSLで構成される構文解析のため

    のtoolkit • PEG(Parsing expression grammar)に基づいている • 特徴は文法規則とSemantic Actionを完全に分離している Ohmʁ
  15. 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 } `);
  16. 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(); } });
  17. 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(); } });
  18. 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() でシンタックスチェック
  19. 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]
  20. 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
  21. 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
  22. 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