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

RubyでLALR(1)パーサージェネレータを作ってみた

Avatar for Kota Kato Kota Kato
June 28, 2025
120

 RubyでLALR(1)パーサージェネレータを作ってみた

Avatar for Kota Kato

Kota Kato

June 28, 2025
Tweet

Transcript

  1. 文法を記述する 例:足し算・掛け算・かっこが記述できる文法 E = E + T | T T

    = T * F | F F = ( E ) | number 終端記号: ( ) * + number 非終端記号: E T F
  2. LR(1)項? A. [ A -> a_1 ・ a_2 , x

    ] 左 辺 右 辺 注 目 点 先 読 み 記 号
  3. T → ・T * F と T → ・F の直後はF

    F → ・( E ) と F → ・i
  4. これを全部をまとめて Closure({ E → E + ・ T }) =

    { E → E + ・ T , T → ・T * F , T → ・F, F → ・( E ) , F → ・i } メモ: 開始規則と注目点が左端にない項をカー ネル項という
  5. 例 I = { E → E + ・ T

    , T → ・T * F , T → ・F, F → ・( E ) , F → ・i } Goto( I, ( )を考える Iの中で注目点の次に(がある規則の集合... { F → ・( E ) } 注目点を一つ動かす { F → ( ・ E ) } Closureを取るClosure({ F → ( ・ E ) })
  6. たとえば、、、 四則演算 expr = expr + expr | expr *

    expr | num これはコンフリクトする、、、が、演算子の 優先度が分かれば解決できる 1 + 1 + 1 は (1 + 1) + 1なの?1 + (1 + 1)なの? 1 + 2 * 3 は(1 + 2) * 3なの?1 + (2 * 3)なの?
  7. ↓コンフリクト解消のログ 状態14で+が入力の時コンフリクトが検出されました [expr → expr * expr ・, $/+///*/-/^] [expr

    → expr ・+ expr, $/+///*/-/^] [expr → expr ・/ expr, $/+///*/-/^] [expr → expr ・* expr, $/+///*/-/^] [expr → expr ・- expr, $/+///*/-/^] [expr → expr ・^ expr, $/+///*/-/^] shiftの優先度: 0 reduceの優先度: 1 > reduceを選択 *と+のどっちを優先すればいいか分からないので → 優先度表を見ると*の方が高い → ので、さきにreduceする *のあとに... +を入力する
  8. 参考文献 湯淺 太一, コンパイラ, 情報系教科書シリーズ , オーム社, 2014年9月, ISBN: 978-4-274-21620-6.

    中田育男, コンパイラ[第2版] サイエンス社, 2009年, ISBN: 978-4-7819-1229-5. A.V. エイホ, M.S. ラム, R. セシィ, J.D. ウルマン 共著, 原田 賢一 訳, コンパイラ[第2 版], サイエンス社, 2009年5月25日, ISBN: 978-4-7819-1229-5 Free Software Foundation, GNU Bison Manual, Version 3.8.1, Section 5.7: Mysterious Conflicts, 10 September 2021, https://www.gnu.org/software/bison/manual/html_node/Mysterious-Conflicts.html 小林 純一, LRでJSONパーサーを作る / Coding LR JSON Parser 大阪Ruby会議04 スポンサー LT, 2024年8月24日, https://speakerdeck.com/junk0612/coding-json-lr-parser yui-knk-blog yui-knk, yui-knk's blog, https://yui-knk.hatenablog.com/