Question

J'essaie de m'apprendre le générateur de grammaire Ruby's Treetop.Je constate que non seulement la documentation est terriblement rare pour la « meilleure » du marché, mais qu'elle ne semble pas fonctionner aussi intuitivement que je l'espérais.

À un niveau élevé, j'aimerais vraiment un meilleur tutoriel que la documentation sur site ou la vidéo, s'il y en a une.

À un niveau inférieur, voici une grammaire sur laquelle je n'arrive pas du tout à travailler :

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

Lorsque je le charge et exécute quelques assertions dans un objet de test très simple, je trouve :

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

Fonctionne bien, tandis que

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

génère l'erreur :Aucune erreur de méthode :méthode privée `eval' appelée pour #

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

Un peu plus d'informations qui peuvent aider.Voici les informations 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 des nombres entiers, mais n'a pas pris en compte 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 résolu mon problème particulier, mais je ne sais pas pourquoi :

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

Cela n'a aucun sens avec les documents présents, mais la simple suppression des parenthèses supplémentaires a permis à la correspondance d'inclure la classe Integer1 ainsi que Integer0.Integer1 est apparemment la classe contenant la méthode eval().Je n'ai aucune idée de pourquoi c'est le cas.

Je cherche toujours plus d'informations sur la cime des arbres.

Était-ce utile?

La solution

Malheureusement, la documentation arboricole suce. Beaucoup. Et les exemples sur le site ne sont pas utiles. Je trouve que DZone a une assez grande collection de grammaires hébertisme:

arboricole Grammaires

Autres conseils

Vous pourriez apprécier bien, tutoriel de Paul Battley à Mise en route avec arboricole

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

Roland Swingler a présenté un exposé sur arboricole à LRUG: http://skillsmatter.com/podcast/ajax-ria/treetop que j'ai trouvé utile de commencer.

Citrus est une alternative beaucoup plus léger à la cime des arbres: http://github.com/mjijackson/citrus

j'ai suivi ça Tutoriel d'introduction à la cime des arbres il y a quelques années pour comprendre les bases de la cime des arbres.

Et puis Une introduction rapide à l'écriture d'un analyseur avec Treetop, utile pour moi car il explique comment mapper les nœuds de l'arborescence syntaxique aux instances de classe Ruby.

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.

Les arboricoles docs semblent supposer que vous savez déjà une bonne quantité au sujet (PEGs) expression analyse syntaxique grammaires . Treetop est entièrement basé sur PEGs. PEGs sont plus grandes que juste TreeTop si, à savoir qu'ils sont utilisés dans d'autres bibliothèques d'analyse syntaxique ainsi. En apprenant arboricole, je l'ai trouvé très utile d'étudier sur PEGs en général. Cela a contribué à remplir un grand nombre de lacunes dans la documentation.

Ceci est un bug. Les parenthèses inutiles autour de la règle pour un nombre entier provoque la construction d'un module supplémentaire pour contenir la définition de eval, et ce module ne soit pas mélangé au nœud, donc « eval » est pas disponible. Vous pouvez voir clairement si l'on compare le code Ruby (généré en utilisant la commande tt) pour les versions avec et sans ces parenthèses supplémentaires.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top