2009-02-06 6 views
16

J'essaie de m'enseigner moi-même le générateur de grammaire Treetop de Ruby. Je constate que non seulement la documentation est tristement rare pour le «meilleur», mais qu'elle ne semble pas fonctionner aussi intuitivement que je l'espérais. En gros, j'adorerais un meilleur tutoriel que les docs sur site ou la vidéo, s'il y en a un.Learning Treetop

Au niveau inférieur, voici une grammaire que je ne peux pas travailler du tout:

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 

Quand je charge et exécuter certaines assertions dans un objet de test très simple, je trouve:

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

fonctionne très bien, tandis que

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

soulève l'erreur: NoMethodError: méthode privée `eval » a appelé à #

Si j'inverse l'entier et flotte sur la description, les entiers et les flottants me donnent cette erreur. Je pense que cela peut être lié à lookahead limité, mais je ne trouve aucune information dans l'un des docs pour même couvrir l'idée d'évaluer dans le contexte "ou"

Un peu plus d'informations qui peuvent aider. Voici des informations sur pp pour ces deux blocs parse().

Le flotteur:

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" 

L'entier ... Notez qu'il semble avoir été défini pour suivre la règle entière, mais pas pris la méthode eval():

SyntaxNode+Integer0 offset=0, "3" (plain_digits): 
    SyntaxNode offset=0, "" 
    SyntaxNode+PlainDigits0 offset=0, "3": 
    SyntaxNode offset=0, "3" 
    SyntaxNode offset=1, "" 

Mise à jour :

j'ai eu mon problème particulier de travail, mais je n'ai aucune idée pourquoi:

rule integer 
    ('+'/'-')? plain_digits 
    { 
     def eval 
     text_value.to_i 
     end 
    } 
    end 

Cela n'a aucun sens avec les documents présents, mais le simple fait de supprimer les parenthèses supplémentaires fait que la correspondance inclut la classe Integer1 ainsi que Integer0. Integer1 est apparemment la classe qui contient la méthode eval(). Je n'ai aucune idée de pourquoi c'est le cas. Je suis toujours à la recherche de plus d'informations sur Treetop.

Répondre

10

Malheureusement, la documentation de Treetop est nulle. Beaucoup. Et les exemples sur le site ne sont pas utiles. Je trouve que DZone a une collection assez grand nombre de grammaires hébertisme:

Treetop grammars

+0

Merci;) Je vais comprendre à travers ce – user54650

+1

bonne chance! peut-être que vous pourriez écrire un article/tutoriel après que vous avez terminé? – Geo

+6

Malheureusement, la page est désactivée pour une raison quelconque. –

1

Je viens juste de commencer à expérimenter avec TreeTop.

J'ai essayé le changement

rule num 
     (float/integer) 
end 

à

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

Et il semble fonctionner.

15

Vous pourriez apprécier bien, tutoriel de Paul Battley à Getting started with Treetop

A partir d'une grammaire minimale, il montre comment créer un analyseur, puis à travers quelques itérations ajoute un peu de fonctionnalité. C'était juste assez pour me sortir des starting-blocks.

0

TREETOP docs semblent supposer que vous savez déjà une bonne quantité à propos de l'expression analyse syntaxique Grammaires (PEGs). Treetop est entièrement basé sur PEG. Cependant, les PEG sont plus gros que Treetop, c'est-à-dire qu'ils sont également utilisés dans d'autres bibliothèques d'analyse. En apprenant Treetop, j'ai trouvé très utile d'étudier les PEG en général. Cela a aidé à combler un grand nombre de lacunes dans la documentation.

0

Ceci est un bug. Les parenthèses inutiles autour de la règle pour un entier provoquent la construction d'un module supplémentaire pour contenir la définition d'eval, et ce module n'est pas mélangé au nœud, donc 'eval' n'est pas disponible. Vous pouvez le voir clairement si vous comparez le code Ruby (généré à l'aide de la commande tt) pour les versions avec et sans ces parenthèses supplémentaires.

Questions connexes