🍣

Ruby 3.3 で Prism のパーサーを使用する

2024/09/12に公開

Prism とは次世代の Ruby のパーサーになります。
Ruby 3.3 から本体にバンドルされており、次のように任意の Ruby のソースコードを Prism でパースさせることができます。

require "prism"

source = <<~EOS
1 + 2
EOS

pp Prism.parse(source)
__END__
output:
#<Prism::ParseResult:0x0000781c578e23f8
 @comments=[],
 @data_loc=nil,
 @errors=[],
 @magic_comments=[],
 @source=#<Prism::Source:0x0000781c57838858 @offsets=[0, 6], @source="1 + 2\n", @start_line=1>,
 @value=
  @ ProgramNode (location: (1,0)-(1,5))
  ├── locals: []
  └── statements:
      @ StatementsNode (location: (1,0)-(1,5))
      └── body: (length: 1)
          └── @ CallNode (location: (1,0)-(1,5))
              ├── flags: ∅
              ├── receiver:
              │   @ IntegerNode (location: (1,0)-(1,1))
              │   └── flags: decimal
              ├── call_operator_loc: ∅
              ├── name: :+
              ├── message_loc: (1,2)-(1,3) = "+"
              ├── opening_loc: ∅
              ├── arguments:
              │   @ ArgumentsNode (location: (1,4)-(1,5))
              │   ├── flags: ∅
              │   └── arguments: (length: 1)
              │       └── @ IntegerNode (location: (1,4)-(1,5))
              │           └── flags: decimal
              ├── closing_loc: ∅
              └── block:,
 @warnings=[]>

Prism に関してはここでは解説しませんが、気になる人は以下の記事などを参照するとよいでしょう。

Ruby 3.3 で Prism パーサーを利用する

Ruby 3.3 では --parser=prism オプションで使用するパーサーを指定することができます。

# デフォルトでは parse.y が使用される
$ ruby -v
ruby 3.3.5 (2024-09-03 revision ef084cc8f4) [x86_64-linux]
# --parser=prism で Prism をパーサーで使用する
$ ruby -v --parser=prism
ruby: warning: The compiler based on the Prism parser is currently experimental and compatibility with the compiler based on parse.y is not yet complete. Please report any issues you find on the `ruby/prism` issue tracker.
ruby 3.3.5 (2024-09-03 revision ef084cc8f4) +PRISM [x86_64-linux]

ただ Ruby 3.3 時点ではまだ不安定なので意図しない挙動が発生する可能性があるので注意してください。
例えば以下のようなコードは parse.y だとシンタックスエラーになりますが prism だとエラーになりません。

# parse.y => syntax error, unexpected local variable or method (SyntaxError)
# prism => no error
def plus(a: 1, b)
  a + b
end

plus(2)

ちなみに開発版の Ruby 3.4 では検証のため、Prism がデフォルトのパーサーとなっています(Ruby 3.4 では上記のバグも治ってます。

$ ruby -v
ruby 3.4.0dev (2024-09-15T01:06:11Z master 532af89e3b) +PRISM [x86_64-linux]

またこのときに parse.y を利用したい場合は --parser=parse.y を指定することで利用できます。

$ ruby -v --parser=parse.y
ruby 3.4.0dev (2024-09-15T01:06:11Z master 532af89e3b) [x86_64-linux]

Ruby 3.4 のデフォルトのパーサーが Prism になるかどうかはまだ確定していませんがエラーメッセージなどがわかりやすくなっているので期待したいですねー。

GitHubで編集を提案

Discussion