Cima di albero di analisi SGF
Domanda
Al momento sto cercando di scrivere una grammatica Treetop per analizzare semplici file di formato di gioco, e sono per lo più di lavoro finora. Tuttavia, ci sono alcune domande che sono venuti.
- Sono incerto come accedere in realtà la struttura Treetop genera dopo un parse.
- C'è un modo migliore per gestire l'acquisizione di tutti i caratteri che la mia regola di caratteri?
-
C'è un caso per i commenti che io non riesco a scrivere correttamente.
C [player1 [4k \]: hi player2 [3k \]: hi]
Non posso avvolgere la mia testa intorno a come trattare con la struttura annidata del [] il nodo C con [] s 'al loro interno.
Quello che segue è il mio progresso corrente.
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
E il mio banco di prova, attualmente escluso C [] nodi con il problema staffa nidificato di cui sopra:
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])")
Soluzione
- La struttura torna a voi come un albero di SyntaxNodes (se il risultato è pari a zero, controllare parser.failure_reason). Si può camminare questo albero o (e questo è consigliata) si può aumentare con le funzioni che fare quello che vuoi e basta chiamare la funzione principale sulla radice.
Se quello che vuoi dire è "come si fa a accedere ai componenti all'interno di una funzione di nodo?" ci sono diversi modi. Si può arrivare a loro con l'elemento [x] notazione o regola:
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
}
È inoltre possibile assegnare un nome in questo modo:
rule phone_number
"(" area_code:( digit digit digit ) ")" ...
e quindi fare riferimento al loro nome.
-
Il tuo caratteri regola guarda bene se desideri solo per abbinare quei personaggi. Se si desidera far corrispondere qualsiasi di carattere si può semplicemente utilizzare un punto (.) Come in un'espressione regolare.
-
Non ho dimestichezza con la lingua che si sta tentando di analizzare, ma la regola che si sta cercando può essere qualcosa come:
rule comment "C" balanced_square_bracket_string end rule balanced_square_bracket_string "[" ( [^\[\]] / balanced_square_bracket_string )* "]" end
La parte centrale del secondo regola corrisponde tutto ciò che non è una parentesi quadra o una stringa nidificato con staffe balanced_square.
P.S. C'è un piuttosto attivo gruppo Google , con gli archivi on-line e consultabile.