iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0
自我挑戰組

C again系列 第 19

用 Ripper 看 tokens, AST

  • 分享至 

  • xImage
  •  

parse.y parse.c 負責兩個工作,將 Ruby code 變成 token 後比對 grammar 建立 AST

Ripper 看產生的 tokens

  #   require 'ripper'
  #   require 'pp'
  #
  #   pp Ripper.lex("def m(a) nil end")
  #   #=> [[[1,  0], :on_kw,     "def", FNAME    ],
  #        [[1,  3], :on_sp,     " ",   FNAME    ],
  #        [[1,  4], :on_ident,  "m",   ENDFN    ],
  #        [[1,  5], :on_lparen, "(",   BEG|LABEL],
  #        [[1,  6], :on_ident,  "a",   ARG      ],
  #        [[1,  7], :on_rparen, ")",   ENDFN    ],
  #        [[1,  8], :on_sp,     " ",   BEG      ],
  #        [[1,  9], :on_kw,     "nil", END      ],
  #        [[1, 12], :on_sp,     " ",   END      ],
  #        [[1, 13], :on_kw,     "end", END      ]]

Ripper 是用 C 實作的 Ruby extension (參考 https://docs.ruby-lang.org/en/3.2/extension_rdoc.html )

在 ripper.c 可以找到實作

void
InitVM_ripper(void)
{
    VALUE Ripper;

    Ripper = rb_define_class("Ripper", rb_cObject);
    /* version of Ripper */
    rb_define_const(Ripper, "Version", rb_usascii_str_new2(RIPPER_VERSION));
    rb_define_alloc_func(Ripper, ripper_s_allocate);
    rb_define_method(Ripper, "initialize", ripper_initialize, -1);
    rb_define_method(Ripper, "parse", ripper_parse, 0);
    // ...

ripper.c 是經由 parse.c 產生的檔案,裡面有幾乎相同用來 parse ruby code 的 C function。從 Ripper.lex 的 Ruby code 一路可以看到 ripper_parse, ripper_parse0, ripper_yyparse 呼叫到 yyparse。單純只研究 parser 的話可以從 ripper 實作來看,少了很多 YARV 的操作。


上一篇
Ruby code to YARV C code
下一篇
用 Ripper 看 tokens, AST (2)
系列文
C again30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言