ruby - tracks - treehouse courses list
Aprendiendo Treetop (8)
Estoy tratando de enseñarme el generador de gramática Treetop de Ruby. Estoy descubriendo que no solo la documentación es escasamente escasa para el "mejor" que existe, sino que no parece funcionar tan intuitivamente como esperaba.
En un alto nivel, realmente me encantaría un tutorial mejor que los documentos in situ o el video, si es que hay alguno.
En un nivel inferior, aquí hay una gramática que no puedo poner en práctica:
grammar SimpleTest
rule num
(float / integer)
end
rule float
(
(( ''+'' / ''-'')? plain_digits ''.'' plain_digits) /
(( ''+'' / ''-'')? plain_digits (''E'' / ''e'') plain_digits ) /
(( ''+'' / ''-'')? plain_digits ''.'') /
(( ''+'' / ''-'')? ''.'' plain_digits)
) {
def eval
text_value.to_f
end
}
end
rule integer
(( ''+'' / ''-'' )? plain_digits) {
def eval
text_value.to_i
end
}
end
rule plain_digits
[0-9] [0-9]*
end
end
Cuando lo cargo y ejecuto algunas afirmaciones en un objeto de prueba muy simple, encuentro:
assert_equal @parser.parse(''3.14'').eval,3.14
Funciona bien, mientras
assert_equal @parser.parse(''3'').eval,3
plantea el error: NoMethodError: método privado `eval ''pidió #
Si invierto el entero y floto en la descripción, tanto los enteros como los flotantes me dan este error. Creo que esto puede estar relacionado con la búsqueda limitada, pero no puedo encontrar ninguna información en ninguno de los documentos ni siquiera para cubrir la idea de evaluar en el contexto "o"
Un poco más de información que puede ayudar. Aquí hay información de pp para ambos bloques de análisis ().
El flotador:
SyntaxNode+Float4+Float0 offset=0, "3.14" (eval,plain_digits):
SyntaxNode offset=0, ""
SyntaxNode+PlainDigits0 offset=0, "3":
SyntaxNode offset=0, "3"
SyntaxNode offset=1, ""
SyntaxNode offset=1, "."
SyntaxNode+PlainDigits0 offset=2, "14":
SyntaxNode offset=2, "1"
SyntaxNode offset=3, "4":
SyntaxNode offset=3, "4"
El número entero ... tenga en cuenta que parece haberse definido para seguir la regla de enteros, pero no capturó el método eval ():
SyntaxNode+Integer0 offset=0, "3" (plain_digits):
SyntaxNode offset=0, ""
SyntaxNode+PlainDigits0 offset=0, "3":
SyntaxNode offset=0, "3"
SyntaxNode offset=1, ""
Actualizar:
Tengo mi problema particular funcionando, pero no tengo idea de por qué:
rule integer
( ''+'' / ''-'' )? plain_digits
{
def eval
text_value.to_i
end
}
end
Esto no tiene sentido con los documentos que están presentes, sino que simplemente quita los paréntesis adicionales que hacen que la coincidencia incluya la clase Integer1 así como Integer0. Integer1 es aparentemente la clase que contiene el método eval (). No tengo idea de por qué este es el caso.
Todavía estoy buscando más información sobre treetop.
Lamentablemente, la documentación de Treetop apesta. Mucho. Y los ejemplos en el sitio web no son útiles. Descubrí que dzone tiene una colección bastante grande de gramáticas en los árboles:
Acabo de comenzar a experimentar con TreeTop.
Probé el cambio
rule num
(float / integer)
end
a
rule num
(float / integer)
{
def eval
text_value.to_f
end
}
end
Y parece funcionar.
Usted podría apreciar el sencillo y sencillo tutorial de Paul Battley en Primeros pasos con Treetop
Comenzando con una gramática mínima, muestra cómo crear un analizador y luego a través de un par de iteraciones agrega solo un poco de funcionalidad. Fue suficiente para sacarme de los puntos de partida.
Roland Swingler hizo una presentación en Treetop para LRUG: http://skillsmatter.com/podcast/ajax-ria/treetop que encontré útil para comenzar.
Citrus es una alternativa mucho más ligera a la copa de los árboles: http://github.com/mjijackson/citrus
Los documentos Treetop parecen suponer que ya sabes bastante sobre el análisis de gramáticas de expresión (PEG). Treetop se basa completamente en PEG. Sin embargo, los PEG son más grandes que Treetop, es decir, también se usan en otras bibliotecas de análisis. Al aprender Treetop, me pareció muy útil estudiar PEG en general. Eso ayudó a llenar muchos vacíos en la documentación.
Seguí este Tutorial introductorio Treetop hace un par de años para entender los conceptos básicos de treetop.
Y luego Una introducción rápida a la escritura de un analizador con Treetop , útil para mí porque explica cómo mapear los nodos de árbol de sintaxis a las instancias de la clase Ruby.
Este es un error. Los paréntesis innecesarios alrededor de la regla para un entero hace que la construcción de un módulo adicional contenga la definición de eval, y este módulo no se mezcla en el nodo, por lo que ''eval'' no está disponible. Puede ver esto claramente si compara el código de Ruby (generado con el comando tt) para las versiones con y sin estos paréntesis adicionales.