模块 RubyVM::AbstractSyntaxTree
AbstractSyntaxTree
提供了将 Ruby 代码解析为抽象语法树的方法。树中的节点是 RubyVM::AbstractSyntaxTree::Node
的实例。
此模块是 MRI 特有的,因为它暴露了 MRI 抽象语法树的实现细节。
此模块是实验性的,其 API 不稳定,因此可能会在不通知的情况下更改。例如,子节点的顺序不保证,子节点的数量可能会更改,没有办法通过名称访问子节点等。
如果您正在寻找稳定的 API 或在多个 Ruby 实现下工作的 API,请考虑使用 prism gem,它是用于解析 Ruby 代码的官方 Ruby API。
公共类方法
返回给定回溯位置的节点 ID。
begin raise rescue => e loc = e.backtrace_locations.first RubyVM::AbstractSyntaxTree.node_id_for_backtrace_location(loc) end # => 0
# File ruby_3_4_1/ast.rb, line 110 def self.node_id_for_backtrace_location backtrace_location Primitive.node_id_for_backtrace_location backtrace_location end
返回给定 *proc* 或 *method* 的 AST 节点。
RubyVM::AbstractSyntaxTree.of(proc {1 + 2}) # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:35-1:42> def hello puts "hello, world" end RubyVM::AbstractSyntaxTree.of(method(:hello)) # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-3:3>
有关关键字参数的含义和用法的说明,请参见 ::parse
。
# File ruby_3_4_1/ast.rb, line 95 def self.of body, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false Primitive.ast_s_of body, keep_script_lines, error_tolerant, keep_tokens end
将给定的 *string* 解析为抽象语法树,并返回该树的根节点。
RubyVM::AbstractSyntaxTree.parse("x = 1 + 2") # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-1:9>
如果提供了 keep_script_lines: true
选项,则解析后的源文本将与节点关联,并且可以通过 Node#script_lines
访问。
如果提供了 keep_tokens: true
选项,则会填充 Node#tokens
。
如果给定的 *string* 是无效语法,则会引发 SyntaxError
。要覆盖此行为,可以提供 error_tolerant: true
。在这种情况下,解析器将生成一个树,其中包含语法错误的表达式将由 type=:ERROR
的 Node
表示。
root = RubyVM::AbstractSyntaxTree.parse("x = 1; p(x; y=2") # <internal:ast>:33:in `parse': syntax error, unexpected ';', expecting ')' (SyntaxError) # x = 1; p(x; y=2 # ^ root = RubyVM::AbstractSyntaxTree.parse("x = 1; p(x; y=2", error_tolerant: true) # (SCOPE@1:0-1:15 # tbl: [:x, :y] # args: nil # body: (BLOCK@1:0-1:15 (LASGN@1:0-1:5 :x (LIT@1:4-1:5 1)) (ERROR@1:7-1:11) (LASGN@1:12-1:15 :y (LIT@1:14-1:15 2)))) root.children.last.children # [(LASGN@1:0-1:5 :x (LIT@1:4-1:5 1)), # (ERROR@1:7-1:11), # (LASGN@1:12-1:15 :y (LIT@1:14-1:15 2))]
请注意,即使在错误表达式之后,解析也会继续。
# File ruby_3_4_1/ast.rb, line 57 def self.parse string, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false Primitive.ast_s_parse string, keep_script_lines, error_tolerant, keep_tokens end
从 *pathname* 读取文件,然后像 ::parse
一样解析它,返回抽象语法树的根节点。
如果 *pathname* 的内容不是有效的 Ruby 语法,则会引发 SyntaxError
。
RubyVM::AbstractSyntaxTree.parse_file("my-app/app.rb") # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-31:3>
有关关键字参数的含义和用法的说明,请参见 ::parse
。
# File ruby_3_4_1/ast.rb, line 74 def self.parse_file pathname, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false Primitive.ast_s_parse_file pathname, keep_script_lines, error_tolerant, keep_tokens end