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

Ecosystem on parse.y

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for S.H. S.H.
February 28, 2026
11

Ecosystem on parse.y

福岡Rubyist会議05

Avatar for S.H.

S.H.

February 28, 2026
Tweet

Transcript

  1. C拡張での実装 VALUE integer_node_new(const NODE *node) { VALUE result = rb_class_new_instance(0,

    0, rb_cIntegerNode); // CRubyのASTが持つ値をインスタンス変数へ詰める rb_ivar_set(result, rb_intern("@val"), rb_node_integer_literal_val(node)); rb_ivar_set(result, rb_intern("@minus"), RNODE_INTEGER(node)->minus == TRUE ? Qtrue : Qfalse); rb_ivar_set(result, rb_intern("@base"), INT2FIX(RNODE_INTEGER(node)->base)); return result; }
  2. KanayagoのLSPの強み PrismとRuby LSPでもできるが、エッジケー スはすり抜ける Kanayagoでは除外できる a rescue b => c

    in d # PrismではSyntaxErrorにならない # parse.yではSyntaxErrorになる # [Bug #21713] # https://bugs.ruby-lang.org/issues/21713
  3. LSPサーバを実装 def analyze(source) diagnostics = [] # KanayagoでソースコードをASTへ変換 result =

    Kanayago.parse(source) # SyntaxErrorの場合はエラー情報を詰める if result.invalid? error = result.error diagnostic = create_diagnostic(error, result.script_lines) diagnostics << diagnostic end diagnostics end
  4. 出力例(Minitestの場合) # frozen_string_literal: true require "test_helper" class UserTest < Minitest::Test

    def test_initialize # Arguments: # - name (required) # - age (required) skip "Not implemented yet" end def test_adult? # Comparisons: >= (@age >= 18) # Boundary value suggestions: # @age >= 18: [17 (below), 18 (boundary), 19 (above)] skip "Not implemented yet" end end
  5. 修正したコード例 VALUE vparser = TypedData_Make_Struct(0, struct ruby_parser, &ruby_parser_data_type, parser); /*

    ... */ VALUE vast = rb_parser_compile_string(vparser, "main", source, 0); rb_ast_t *ast = rb_ruby_ast_data_get(vast); VALUE ast_node = ast_to_node_instance(ast->body.root); // vast、vparserがGCされるとSegmentation faultになる // GCされないようにガードを付けている RB_GC_GUARD(vast); RB_GC_GUARD(vparser);