模組 RubyVM::AbstractSyntaxTree

AbstractSyntaxTree 提供將 Ruby 程式碼解析成抽象語法樹的方法。樹中的節點是 RubyVM::AbstractSyntaxTree::Node 的執行個體。

此模組是 MRI 專用的,因為它公開 MRI 抽象語法樹的實作細節。

此模組是實驗性質的,其 API 不穩定,因此可能會在沒有預告的情況下變更。例如,子節點的順序無法保證,子節點的數量可能會變更,無法依名稱存取子節點等。

如果您正在尋找穩定的 API 或在多個 Ruby 實作中運作的 API,請考慮使用 parser gem 或 Ripper。如果您想讓 RubyVM::AbstractSyntaxTree 穩定,請加入 bugs.ruby-lang.org/issues/14844 的討論。

公開類別方法

RubyVM::AbstractSyntaxTree.node_id_for_backtrace_location(backtrace_location) → integer 按一下以切換來源

傳回給定回溯位置的節點 ID。

begin
  raise
rescue =>  e
  loc = e.backtrace_locations.first
  RubyVM::AbstractSyntaxTree.node_id_for_backtrace_location(loc)
end # => 0
# File ast.rb, line 111
def self.node_id_for_backtrace_location backtrace_location
  Primitive.node_id_for_backtrace_location backtrace_location
end
RubyVM::AbstractSyntaxTree.of(proc, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) → RubyVM::AbstractSyntaxTree::Node 按一下以切換來源
RubyVM::AbstractSyntaxTree.of(method, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) → RubyVM::AbstractSyntaxTree::Node

傳回給定 procmethod 的 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 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
RubyVM::AbstractSyntaxTree.parse(string, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) → RubyVM::AbstractSyntaxTree::Node 按一下以切換來源

將給定的字串剖析成抽象語法樹,傳回該樹的根節點。

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。在這種情況下,剖析器會產生一棵樹,其中語法錯誤的表達式會以 type=:ERRORNode 表示。

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 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_file(pathname, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) → RubyVM::AbstractSyntaxTree::Node 按一下以切換來源

pathname 讀取檔案,然後像 ::parse 一樣剖析它,傳回抽象語法樹的根節點。

如果 pathname 的內容不是有效的 Ruby 語法,會引發 SyntaxError

RubyVM::AbstractSyntaxTree.parse_file("my-app/app.rb")
# => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-31:3>

請參閱 ::parse 以了解關鍵字引數的意義和用法。

# 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