Domanda

Sto cercando di insegnare a me stesso generatore di grammatica Cima di Ruby. Mi sto trovando che non solo è la documentazione tristemente sparse per il "migliore" là fuori, ma che non sembra funzionare come intuitivamente come avevo sperato.

A livello alto, mi piacerebbe davvero un tutorial meglio che i documenti in loco o il video, se ce n'è uno.

Su un livello più basso, ecco una grammatica che non posso andare al lavoro a tutti:

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

Quando carico ed eseguire alcune affermazioni in un oggetto di prova molto semplice, ho trovato:

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

Funziona bene, mentre

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

genera l'errore: NoMethodError: metodo privato `eval' chiamato per #

Se io inverto intero e galleggiare sulla descrizione, sia interi e carri allegorici mi danno questo errore. Penso che questo possa essere correlato a lookahead limitata, ma non riesco a trovare alcuna informazione in uno qualsiasi dei documenti per coprire anche l'idea di valutare la "o" di contesto

Un po 'più di informazioni che possono aiutare. Ecco le informazioni pp sia per coloro parse () blocchi.

Il galleggiante:

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'intero ... notare che sembra essere stata definita di seguire la regola numero intero, ma non prese il metodo eval ():

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

Aggiornamento:

ho ottenuto il mio problema particolare di lavoro, ma non ho idea perché:

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

Questo non ha senso con i documenti che sono presenti, ma solo rimuovendo le parentesi aggiuntive fatto la partita comprendono la classe Intero1 così come Integer0. Intero1 è apparentemente la classe tenendo il metodo eval (). Non ho idea del perché questo è il caso.

Sono ancora alla ricerca di maggiori informazioni su cime degli alberi.

È stato utile?

Soluzione

Purtroppo, la documentazione di Treetop fa schifo. Un sacco. E gli esempi sul sito non sono utili. Ho scoperto che DZone ha una bella collezione di grammatiche sugli alberi:

Cima di grammatiche

Altri suggerimenti

Si potrebbe apprezzare la bella, semplice tutorial di Paul Battley a Iniziare con Treetop

A partire da una grammatica minima, si mostra come creare un parser e poi attraverso un paio di iterazioni aggiunge solo un po 'di funzionalità. E 'stato appena sufficiente per farmi fuori dai blocchi di partenza.

Roland Swingler ha dato una presentazione su Treetop a LRUG: http://skillsmatter.com/podcast/ajax-ria/treetop che ho trovato utile per iniziare.

Citrus è un'alternativa molto più leggero di cime degli alberi: http://github.com/mjijackson/citrus

Ho seguito questo Treetop introduttiva Tutorial un paio di anni fa, per capire le basi di cime degli alberi.

E poi una rapida introduzione a scrittura di un parser con Treetop , utile per me perché è spiegato come mappare nodi dell'albero sintassi al rubino istanze di classe.

Ho appena iniziato a sperimentare con TreeTop.

Ho provato il cambiamento

 rule num
      (float / integer)
 end

a

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

E sembra funzionare.

La documentazione Cima sembrano dare per scontato che già conosci una discreta quantità su l'analisi di espressione grammatiche (PEG). Cima di albero si basa interamente su PEG. PEG sono più grandi di una semplice Cima di albero, però, vale a dire che sono utilizzati in altre librerie di parsing pure. Nell'apprendimento Cima di albero, ho trovato molto utile per studiare fino a PEG in generale. Che hanno contribuito a compilare un sacco di lacune nella documentazione.

Questo è un bug. Le parentesi non necessarie in tutto il regola per un intero provoca la costruzione di un modulo aggiuntivo per contenere la definizione di eval, e questo modulo non ottiene misto in al nodo, cosi 'eval' non è disponibile. Si può vedere chiaramente se si confronta il codice Ruby (generato usando il comando TT) per le versioni con e senza questi parentesi in più.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top