модуль RubyVM::AbstractSyntaxTree
AbstractSyntaxTree предоставляет методы для разбора кода Ruby в деревья абстрактного синтаксиса. Узлы в дереве являются экземплярами RubyVM::AbstractSyntaxTree::Node.
Этот модуль специфичен для MRI, так как он раскрывает детали реализации дерева абстрактного синтаксиса MRI.
Этот модуль экспериментальный, и его API не стабилен, поэтому он может измениться без предварительного уведомления. Например, порядок дочерних узлов не гарантируется, количество дочерних узлов может измениться, нет возможности получить доступ к дочерним узлам по имени и т. д.
Если вы ищете стабильный API или API, работающий в нескольких реализациях Ruby, рассмотрите использование драгоценности parser или Ripper. Если вы хотите сделать RubyVM::AbstractSyntaxTree стабильным, пожалуйста, присоединяйтесь к обсуждению на bugs.ruby-lang.org/issues/14844.
Публичные методы класса
# File ast.rb, line 111 def self.node_id_for_backtrace_location backtrace_location Primitive.node_id_for_backtrace_location backtrace_location end
Возвращает идентификатор узла для заданной позиции трассировки стека.
begin raise rescue => e loc = e.backtrace_locations.first RubyVM::AbstractSyntaxTree.node_id_for_backtrace_location(loc) end # => 0
# File ast.rb, line 96 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
Возвращает узлы AST заданного proc или method.
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 ast.rb, line 58 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
Разбирает заданную строку в дерево абстрактного синтаксиса, возвращая корневой узел этого дерева.
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 заполняются.
SyntaxError генерируется, если заданная строка имеет недопустимый синтаксис. Чтобы переопределить это поведение, можно предоставить error_tolerant: true. В этом случае анализатор создаст дерево, где выражения со синтаксическими ошибками будут представлены узлами Node с type=:ERROR.
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 ast.rb, line 75 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
Читает файл из pathname, затем разбирает его как ::parse, возвращая корневой узел дерева абстрактного синтаксиса.
SyntaxError генерируется, если содержимое pathname не является допустимым синтаксисом Ruby.
RubyVM::AbstractSyntaxTree.parse_file("my-app/app.rb")
# => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-31:3>
См. ::parse для объяснения значения и использования ключевых аргументов.
Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.