2009-02-06 12 views
16

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.Learning Treetop

En un nivel superior, realmente me encantaría un tutorial mejor que los documentos en el sitio o el video, si es que hay alguno.

En un nivel inferior, aquí está una gramática que no puedo ir a trabajar en absoluto:

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 cargo y ejecutar algunas afirmaciones en un objeto de prueba muy simple, me parece:

assert_equal @parser.parse('3.14').eval,3.14 

funciona bien, mientras que

assert_equal @parser.parse('3').eval,3 

plantea el error: NoMethodError: eval método `privado' pidió #

Si invierto el número 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 información en ninguno de los documentos 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 entero ... en cuenta que parece que ha sido definido a seguir la regla número entero, pero no se detecta 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, "" 

actualización :

tengo mi problema particular de trabajo, pero no tengo ni 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, pero solo eliminando 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.

Respuesta

10

Lamentablemente, la documentación de Treetop apesta. Mucho. Y los ejemplos en el sitio web no son útiles. Me encontré con que DZone tiene una muy gran colección de copas de los árboles gramáticas:

Treetop grammars

+0

Gracias;) Voy a averiguarlo a través de ese – user54650

+1

buena suerte! tal vez podrías escribir algún artículo/tutorial después de que hayas terminado? – Geo

+6

Lamentablemente, la página está deshabilitada por algún motivo. –

1

Acabo de empezar a experimentar con el de TreeTop.

He probado el cambio de

rule num 
     (float/integer) 
end 

a

rule num 
     (float/integer) 
     { 
     def eval 
      text_value.to_f 
     end 
     } 
end 

Y parece que funciona.

15

que te pueden apreciar buen tutorial de Pablo Battley, simple en Getting started with Treetop

A partir de una gramática mínima, que muestra cómo crear un programa de análisis y luego a través de un par de iteraciones añade un poco de funcionalidad. Fue suficiente para sacarme de los puntos de partida.

0

Los documentos Cima del árbol parecen asumir que ya conoce bastante sobre expresión analizar gramáticas (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.

0

trata de 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.