File: PRISM_TRANSLATION.md

package info (click to toggle)
ruby-whitequark-parser 3.3.10.1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 2,848 kB
  • sloc: yacc: 40,706; ruby: 20,588; makefile: 12; sh: 8
file content (80 lines) | stat: -rw-r--r-- 2,308 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# Usage in conjunction with the Prism Parser Translator

Because `parser` only parses Ruby <= 3.3 and `prism` only Ruby >= 3.3, if you want to continue parsing both old and new versions, you need to depend on both `parser` and `prism`.

## Using `prism` when parsing with an explicit Ruby verion

```rb
require 'parser'
require 'prism'

def parser_for_ruby_version(ruby_version)
  case ruby_version
  when 3.1
    require 'parser/ruby31'
    Parser::Ruby31
  when 3.2
    require 'parser/ruby32'
    Parser::Ruby32
  when 3.3
    Prism::Translation::Parser33
  when 3.4
    Prism::Translation::Parser34
  else
    raise 'Unknown Ruby version'
  end
end

parser_for_ruby_version(3.4).parse(<<~RUBY)
  puts 'Hello World!'
RUBY
```

## Using `prism` when parsing ruby for the currently running Ruby version

If you are using `Parser::CurrentRuby`, you need to do similar branching logic:

```rb
def parser_for_current_ruby
  if Gem::Version.new(RUBY_VERSION) <= '3.3'
    require 'parser/current'
    Parser::CurrentRuby
  else
    require 'prism'
    # Only available on prism > 1.4.0
    Prism::Translation::ParserCurrent
  end
end

parser_for_current_ruby.parse(<<~RUBY)
  puts 'Hello World!'
RUBY
```

## Using a custom builder

If you are providing a custom builder (see [Customization](./CUSTOMIZATION.md)), you must create a copy that behaves the same for `prism`, but inherits from a different base class. This is because the builder used internally by `prism` has more functionality for more modern node types, which is lacking in the builder from `parser`.

```rb
# Use a module to not duplicate the implementation
module BuilderExtensions
  def self.inherited(base)
    # Always emit the most modern format available
    base.modernize
  end
end

class BuilderParser < Parser::Builders::Default
  include BuilderExtensions
end

class BuilderPrism < Prism::Translation::Parser::Builder
  include BuilderExtensions
end
```

You can then conditionally use the proper builder class, branching on the version of ruby that will get analyzed.

## New node types

As new syntax gets added to Ruby, the `prism` gem may emit nodes that have no counterpart in the `parser` gem. These nodes will be documented [in the usual place](./AST_FORMAT.md) but are otherwise not supported or emitted by the `parser` gem.