Question
Je suis en train d'écrire actuellement une grammaire arboricole pour analyser les fichiers de format de jeu simple, et faites-le travailler jusqu'à présent la plupart du temps. Cependant, il y a quelques questions qui ont été soulevées.
- Je ne suis pas sûr comment accéder réellement la structure arboricole génère après une analyse syntaxique.
- Y at-il une meilleure façon de gérer la capture tous les caractères que ma règle de caractères?
-
Il y a un cas pour les commentaires que je ne peux pas sembler écrire correctement.
C [player1 [4k \]: salut player2 [3k \]: salut]
Je ne peux pas envelopper la tête autour de la façon de traiter avec la structure imbriquée du noeud C [] avec [] 's à l'intérieur.
Ce qui suit est ma progression actuelle.
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
Et mon cas de test, à l'exclusion en C [] noeuds avec le problème du support imbriqué mentionné ci-dessus:
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])")
La solution
- La structure vous revient comme un arbre de SyntaxNodes (si le résultat est nul, vérifier parser.failure_reason). Vous pouvez marcher cet arbre ou (ce qui est recommandé), vous pouvez l'augmenter avec des fonctions qui font ce que vous voulez et il suffit d'appeler votre fonction principale à la racine.
Si ce que vous voulez dire « comment avez-vous accès aux composants à partir d'une fonction de nœud? » il existe plusieurs façons. Vous pouvez obtenir à eux avec l'élément [x] notation ou par la règle:
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
}
Vous pouvez aussi les nommer comme ceci:
rule phone_number
"(" area_code:( digit digit digit ) ")" ...
puis reportez-vous à leur nom.
-
Votre règle de caractères semble bien si vous voulez seulement correspondre à ces caractères. Si vous voulez faire correspondre any caractère que vous pouvez simplement utiliser un point (.) Comme dans une expression régulière.
-
Je ne suis pas familier avec la langue que vous essayez d'analyser, mais la règle que vous cherchez peut-être quelque chose comme:
rule comment "C" balanced_square_bracket_string end rule balanced_square_bracket_string "[" ( [^\[\]] / balanced_square_bracket_string )* "]" end
La partie centrale de la deuxième règle correspond à tout ce qui est pas un carré ou un support de chaîne imbriquée avec des supports de balanced_square.
P.S. Il y a un groupe Google , avec des archives en ligne et consultable.