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

The Sequel to a Dream of Ruby Parser's Grammar

ydah
August 31, 2024

The Sequel to a Dream of Ruby Parser's Grammar

RubyKaigi 2024 follow up「The Sequel to a Dream of Ruby Parser's Grammar」の発表スライド。
#rubykaigi_followup https://rhc.connpass.com/event/320709/

ydah

August 31, 2024
Tweet

More Decks by ydah

Other Decks in Programming

Transcript

  1. The Sequel to a Dream of Ruby Parser's Grammar RubyKaigi

    2024 follow up 31 August 2024 Yudai Takada (@ydah)
  2. Live Tour 2024 •2024.8.31 (ONLINE) RubyKaigi 2024 followup •2024.9.13 (Sarajevo)

    EuRuKo 2024 •2024.10.25-26 (Tokyo) Kaigi on Rails 2024
  3. expr : NUMBER { $$ = $1; } | expr

    '+' expr { $$ = $1 + $3; } | expr '-' expr { $$ = $1 - $3; } | expr '*' expr { $$ = $1 * $3; } | expr '/' expr { $$ = $1 / $3; } | '(' expr ')' { $$ = $2; } ; BNF ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar
  4. parse.y ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar •File de fi nes the Ruby

    grammar and processing. •Extremely di ff i cult to understand. •Be likened to a Demon Castle, Hell, Monstrous
  5. What's di ffi culty? ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar •Grammar provided by

    Bison is primitive. •Parser and Lexer are tightly coupled. •Di ff i cult to resolve S/R or R/R con fl icts.
  6. opt_args_tail : ',' args_tail { $$ = $2; / *

    % ripper: get_value($ : 2); % * / } | / * none * / { $$ = new_args_tail(p, 0, 0, 0, &@0); / * % ripper: rb_ary_new_from_args(3, Qnil, Qnil, Qnil); % * / } ; ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar
  7. opt_block_args_tail : ',' block_args_tail { $$ = $2; / *

    % ripper: get_value($ : 2); % * / } | / * none * / { $$ = new_args_tail(p, 0, 0, 0, &@0); / * % ripper: rb_ary_new_from_args(3, Qnil, Qnil, Qnil); % * / } ; ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar
  8. opt_args_tail : ',' args_tail { $$ = $2; / *

    % ripper: get_value($ : 2); % * / } | / * none * / { $$ = new_args_tail(p, 0, 0, 0, &@0); / * % ripper: rb_ary_new_from_args(3, Qnil, Qnil, Qnil); % * / } ; ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar ???????
  9. opt_block_args_tail : ',' block_args_tail { $$ = $2; / *

    % ripper: get_value($ : 2); % * / } | / * none * / { $$ = new_args_tail(p, 0, 0, 0, &@0); / * % ripper: rb_ary_new_from_args(3, Qnil, Qnil, Qnil); % * / } ; ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar ????????????
  10. %rules args_tail(tail) : ',' tail { $$ = $2; ɹɹ

    ɹ / * % ripper: get_value($ : 2); % * / } | / * none * / { $$ = new_args_tail(p, 0, 0, 0, &@0); / * % ripper: rb_ary_new_from_args(3, Qnil, Qnil, Qnil); % * / } ; % % opt_args_tail: args_tail(arg_tail) ; opt_block_args_tail : args_tail(blk_tail) ; ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar
  11. %rules args_tail(tail) : ',' tail { $$ = $2; ɹɹ

    ɹ / * % ripper: get_value($ : 2); % * / } | / * none * / { $$ = new_args_tail(p, 0, 0, 0, &@0); / * % ripper: rb_ary_new_from_args(3, Qnil, Qnil, Qnil); % * / } ; % % opt_args_tail: args_tail(arg_tail) ; opt_block_args_tail : args_tail(blk_tail) ; ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar 共通的な構造の定義
  12. %rules args_tail(tail) : ',' tail { $$ = $2; ɹɹ

    ɹ / * % ripper: get_value($ : 2); % * / } | / * none * / { $$ = new_args_tail(p, 0, 0, 0, &@0); / * % ripper: rb_ary_new_from_args(3, Qnil, Qnil, Qnil); % * / } ; % % opt_args_tail: args_tail(arg_tail) ; opt_block_args_tail : args_tail(blk_tail) ; ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar 定義されたルールを使う
  13. %rules args_tail(tail) : ',' tail { $$ = $2; ɹɹ

    ɹ / * % ripper: get_value($ : 2); % * / } | / * none * / { $$ = new_args_tail(p, 0, 0, 0, &@0); / * % ripper: rb_ary_new_from_args(3, Qnil, Qnil, Qnil); % * / } ; % % opt_args_tail: args_tail(arg_tail) ; opt_block_args_tail : args_tail(blk_tail) ; ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar 引数 これが引数として渡る
  14. %rules args_tail(tail) : ',' tail { $$ = $2; ɹɹ

    ɹ / * % ripper: get_value($ : 2); % * / } | / * none * / { $$ = new_args_tail(p, 0, 0, 0, &@0); / * % ripper: rb_ary_new_from_args(3, Qnil, Qnil, Qnil); % * / } ; % % opt_args_tail: args_tail(arg_tail) ; opt_block_args_tail : args_tail(blk_tail) ; ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar 展開される 展開される
  15. if down? if right - lower? if right? if P?

    puts 'Hadouken' end end end end ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar
  16. irb(main) : 001> - > (a) {} = > #<Proc:0

    x 000000012316e698 (irb) : 1 (lambda)> irb(main) : 002> - > (a=1) {} = > #<Proc:0 x 0000000123119918 (irb) : 2 (lambda)> irb(main) : 003> - > ( . . . ) {} <internal:kernel > : 187:in `loop': (irb) : 3 : syntax error, unexpected . . . , expecting ')' (SyntaxError) - > ( . . . ) {} ^ ~ ~ Example ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar
  17. %rule def i ned_rule(X, condition) : %if(condition) X %endif X

    { $$ = $1; } ; % % r_true : def i ned_rule(number, %true) ; r_false : def i ned_rule(number, %false) ; Idea 1 ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar
  18. %rule def i ned_rule(X, condition) : %if(condition) X %endif X

    { $$ = $1; } ; % % r_true : def i ned_rule(number, %true) ; r_false : def i ned_rule(number, %false) ; ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar Idea 1 trueを渡す %if(true)
  19. %rule def i ned_rule(X, condition) : %if(condition) X %endif X

    { $$ = $1; } ; % % r_true : def i ned_rule(number, %true) ; r_false : def i ned_rule(number, %false) ; ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar =>X X { $$ = $1; } Idea 1 ????????????????????????????????
  20. %rule def i ned_rule(X, condition) : %if(condition) X %endif X

    { $$ = $1; } ; % % r_true : def i ned_rule(number, %true) ; r_false : def i ned_rule(number, %false) ; ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar Idea 1 falseを渡す %if(false)
  21. %rule def i ned_rule(X, condition) : %if(condition) X %endif X

    { $$ = $1; } ; % % r_true : def i ned_rule(number, %true) ; r_false : def i ned_rule(number, %false) ; ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar => X { $$ = $1; } Idea 1 ????????????
  22. %rule def i ned_rule(X, condition) : X { $$ =

    $1; } %if(condition) ; % % r_true : def i ned_rule(number, %true) ; r_false : def i ned_rule(number, %false) ; Idea 2 ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar
  23. %rule def i ned_rule(X, condition) : X { $$ =

    $1; } %if(condition) ; % % r_true : def i ned_rule(number, %true) ; r_false : def i ned_rule(number, %false) ; Idea 2 ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar %if(true) trueを渡す
  24. %rule def i ned_rule(X, condition) : X { $$ =

    $1; } %if(condition) ; % % r_true : def i ned_rule(number, %true) ; r_false : def i ned_rule(number, %false) ; Idea 2 ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar ????????????? => X { $$ = $1; }
  25. %rule def i ned_rule(X, condition) : X { $$ =

    $1; } %if(condition) ; % % r_true : def i ned_rule(number, %true) ; r_false : def i ned_rule(number, %false) ; Idea 2 ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar falseを渡す %if(false)
  26. %rule def i ned_rule(X, condition) : X { $$ =

    $1; } %if(condition) ; % % r_true : def i ned_rule(number, %true) ; r_false : def i ned_rule(number, %false) ; Idea 2 ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar ??????????????????????????? => /* empty */
  27. %rule if_example(foo, cond) : foo { $$ = $1; }

    %if(cond) ; % % example : if_example(value, %true) ; Point 1 ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar
  28. %rule if_example(foo, cond) : foo { $$ = $1; }

    %if(cond) ; % % example : if_example(value, %true) ; Point 1 ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar ここ < foo と cond は構文を分けたい
  29. %rule if_example(foo, cond) : foo { $$ = $1; }

    %if(cond) ; % % example : if_example(value, %true) ; Point 2 ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar
  30. %rule if_example(foo, cond) : foo { $$ = $1; }

    %if(cond) ; % % example : if_example(value, %true) ; Point 2 ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar ここ < 条件引数って “式” の一種なのでは?
  31. %rule if_example(foo, cond: Conditional) : foo { $$ = $1;

    } %if(cond) ; % % example : if_example(value, { %true }) ; Proposal ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar < OsakaRubyKaigi04を準備しつつ考えてました
  32. %rule if_example(foo, cond: Conditional) : foo { $$ = $1;

    } %if(cond) ; % % example : if_example(value, { %true }) ; Proposal ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar
  33. %rule if_example(foo, cond: Conditional) : foo { $$ = $1;

    } %if(cond) ; % % example : if_example(value, { %true }) ; Proposal ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar < 式なので、 { foo==bar }の様に書けると良い?
  34. %rule if_example(foo, cond: Conditional) : foo { $$ = $1;

    } %if(cond) ; % % example : if_example(value, { %true }) ; Proposal ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar < まだ少しなやんでいます。。。
  35. %rule if_example(foo, cond: Boolean) : foo { $$ = $1;

    } %if(cond) ; % % example : if_example(value, { %true }) ; Other Proposal ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar < これだと型に見える??
  36. %rule if_example(foo, @cond) : foo { $$ = $1; }

    %if(cond) ; % % example : if_example(value, { %true }) ; Other Proposal ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar < 接頭語をつける案。いい記号があればいいケド
  37. %rule if_example(foo, cond: Conditional) : foo { $$ = $1;

    } %if(cond) ; % % example : if_example(value, { %true }) ; Proposal ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar < という訳でこれが最有力候補です。WDYT?
  38. Wish List ydah | https://speakerdeck.com/ydah/the-sequel-to-a-dream-of-ruby-parsers-grammar •Release v0.6.10 of Lrama. •Adding

    location information to the node structure. < がんばるか、 超がんばるかしかない!!!