Frage
Ich versuche zur Zeit eine Treetop Grammatik zu schreiben einfache Spiel-Format-Dateien zu analysieren, und habe sie meist so weit arbeiten. Es gibt jedoch ein paar Fragen, die kommen haben.
- Ich bin nicht sicher, wie man tatsächlich die Struktur zugreifen Treetop nach einem Parse erzeugt.
- Gibt es einen besseren Weg, um alle Zeichen als mein Zeichen Regel zu behandeln die Erfassung?
-
Es gibt einen Fall für Kommentare, die ich nicht richtig zu schreiben scheinen.
C [player1 [4k \]: hallo player2 [3k \]: hallo]
Ich kann meinen Kopf nicht umschlingen, wie man mit der verschachtelten Struktur der C [] Knoten mit [] 's in sie fertig zu werden.
Die folgend mein aktueller Fortschritt ist.
SGF-grammar.treetop
grammar SgfGrammar
rule node
'(' chunk* ')' {
def value
text_value
end
}
end
rule chunk
';' property_set* {
def value
text_value
end
}
end
rule property_set
property ('[' property_data ']')* / property '[' property_data ']' {
def value
text_value
end
}
end
rule property_data
chars '[' (!'\]' . )* '\]' chars / chars / empty {
def value
text_value
end
}
end
rule property
[A-Z]+ / [A-Z] {
def value
text_value
end
}
end
rule chars
[a-zA-Z0-9_/\-:;|'"\\<>(){}!@#$%^&\*\+\-,\.\?!= \r\n\t]*
end
rule empty
''
end
end
Und mein Testfall, zur Zeit ohne C [] Knoten mit dem oben erwähnten verschachtelten Klammer Problem:
example.rb
require 'rubygems'
require 'treetop'
require 'sgf-grammar'
parser = SgfGrammarParser.new
parser.parse("(;GM[1]FF[4]CA[UTF-8]AP[CGoban:3]ST[2]
RU[Japanese]SZ[19]KM[0.50]TM[1800]OT[5x30 byo-yomi]
PW[stoic]PB[bojo]WR[3k]BR[4k]DT[2008-11-30]RE[B+2.50])")
Lösung
- Die Struktur kommt als Baum von SyntaxNodes an Dich zurück (wenn das Ergebnis gleich Null ist, überprüfen parser.failure_reason). Sie können diesen Baum zu Fuß oder (und dies wird empfohlen) Sie es mit Funktionen erweitern können das tun, was Sie wollen und nur Ihre Hauptfunktion an der Wurzel nennen.
Wenn Sie das meinen ist „Wie greifen Sie die Komponenten aus einer Knotenfunktion?“ gibt es mehrere Möglichkeiten. Sie können mit dem Element bei ihnen bekommen [x] Notation oder durch die Regel:
rule url_prefix
protocol "://" host_name {
def example
assert element[0] == protocol
assert element[2] == host_name
unless protocol.text_value == "http"
print "#{protocol.text_value} not supported"
end
end
}
Sie können sie auch nennen wie folgt:
rule phone_number
"(" area_code:( digit digit digit ) ")" ...
und dann beziehen sich auf sie mit Namen.
-
Ihr Zeichen Regel sieht gut aus, wenn Sie nur die Zeichen übereinstimmen sollen. Wenn Sie vergleichen wollen jeder Zeichen, das Sie nur einen Punkt (.) Wie in einem regulären Ausdruck verwenden können.
-
Ich bin nicht vertraut mit der Sprache, die Sie zu analysieren versuchen, sondern die Regel Sie suchen, kann so etwas wie:
rule comment "C" balanced_square_bracket_string end rule balanced_square_bracket_string "[" ( [^\[\]] / balanced_square_bracket_string )* "]" end
Der mittlere Teil der zweiten Regel entspricht alles, was nicht eine eckige Klammer oder eine verschachtelte String mit balanced_square Klammern ist.
P. S. Es ist ein ziemlich aktiver Google Gruppe , mit Archiven online & durchsuchbar.