This topic has missing or partial documentation. Please help us improve it.
Una vez que el parser ha terminado de llamar los métodos process_*, se crea
un AST, o árbol sintáctico abstracto. Éste representa la estructura sintáctica
abstracta del código fuente analizado. Cada nodo del árbol denota un
constructo en el código fuente. Este árbol está compuesto por instancias de
clases definidas en el directorio lib/compiler/ast/.
Cada una de estas clases hereda de la clase Rubinius::AST::Node.
La clase Node define unos cuantos métodos utilizados por las subclases (por
ejemplo pos(g), que guarda el número de línea para facilitar el proceso de
debugging).
Las clases del AST definen por lo menos 3 métodos:
process_* en la etapa
anterior.La forma más fácil de visualizar el AST a partir de determinado código fuente
es llamar to_ast sobre una cadena que contenga dicho código, por ejemplo:
irb(main):002:0> "a = 1".to_ast
=> #<Rubinius::AST::LocalVariableAssignment:0xf70
@value=#<Rubinius::AST::FixnumLiteral:0xf74 @value=1 @line=1>
@name=:a @variable=nil @line=1>
O bien compilar el código con la opción -A:
rbx compile -A -e "def hello;end"
Script
@name: __script__
@file: "(snippet)"
@body: \
Define
@name: hello
@line: 1
@arguments: \
FormalArguments
@defaults: nil
@names: \
@block_arg: nil
@optional: \
@splat: nil
@line: 1
@required: \
@body: \
Block
@line: 1
@array: \
NilLiteral
@line: 1
De forma similar, es posible obtener una representación del árbol sintáctico como una serie de expresiones-S:
irb(main):002:0> "a = 1".to_sexp
=> [:lasgn, :a, [:lit, 1]]
O bien pasar la opción -S al compilar:
rbx compile -S -e "def hello;end"
[:script, [:defn, :hello, [:args], [:scope, [:block, [:nil]]]]]
El AST es una estructura anidada donde nodos contienen otros nodos. Por
ejemplo, el método hello definido más arriba está compuesto de un nodo
Script que contiene Define en su @body, el cual a su vez contiene
FormalArguments en sus @arguments y Block en su @body. El nodo Block
contiene solamente un NilLiteral en su @array. El nodo NilLiteral es una
hoja del árbol: no contiene ningún otro nodo.
Es importante tener en cuenta que la siguiente expresión if:
rbx compile -S -e ":foo if :bar"
[:script, [:if, [:lit, :bar], [:lit, :foo], nil]]
y la misma expresión if escrita de forma distinta:
rbx compile -S -e "if :bar then :foo; end"
[:script, [:if, [:lit, :bar], [:lit, :foo], nil]]
producen exactamente el mismo árbol sintáctico. El hecho de que el árbol no represente cada detalle que aparece en la sintaxis real es el motivo por el cual se llama “abstracto”.
Hay dos maneras de personalizar esta etapa del proceso de compilación. La forma más sencilla de personalizar la creación del AST es a través de las Transformaciones del AST.
También se puede heredar del procesador Melbourne y definir “handlers” para
los métodos process_. Éste es un tema avanzado que no está documentado
todavía.