模組 RubyVM::AbstractSyntaxTree
AbstractSyntaxTree
提供將 Ruby 程式碼解析成抽象語法樹的方法。樹中的節點是 RubyVM::AbstractSyntaxTree::Node
的執行個體。
此模組是 MRI 專用的,因為它公開 MRI 抽象語法樹的實作細節。
此模組是實驗性質的,其 API 不穩定,因此可能會在沒有預告的情況下變更。例如,子節點的順序無法保證,子節點的數量可能會變更,無法依名稱存取子節點等。
如果您正在尋找穩定的 API 或在多個 Ruby 實作中運作的 API,請考慮使用 parser gem 或 Ripper
。如果您想讓 RubyVM::AbstractSyntaxTree
穩定,請加入 bugs.ruby-lang.org/issues/14844 的討論。
公開類別方法
傳回給定回溯位置的節點 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
傳回給定 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 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("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=: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 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
從 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