2009-02-28 11 views
3

Şu anda Simple Game Format dosyalarını ayrıştırmak için bir Treetop dilbilgisi yazmaya çalışıyorum ve çoğunlukla şu ana kadar çalışıyorum. Ancak, ortaya çıkan birkaç soru var.Treetop SGF Ayrıştırma

  1. Treetop'un bir ayrıştırmadan sonra oluşturduğu yapıya gerçekten nasıl erişeceğinden emin değilim.
  2. Tüm karakterleri yakalamak için benim karakter kuralımdan daha iyi bir yol var mı?
  3. Doğru yazamadığım yorumlar için bir durum var.

    C [player1 [4k \]: hi player2 [3k \]:! Hi] ben kafamı kaydıramazsınız

nasıl C [] düğümün iç içe yapısıyla başa [] ile onların içinde.

Aşağıdaki işlem şu andaki işlemim.

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_/\-:;|'"\\<>(){}[email protected]#$%^&\*\+\-,\.\?!= \r\n\t]* 
end 

rule empty 
    '' 
end 
end 

Ve test durumda, şu anda yukarıda belirtilen iç içe dirsek sorun söz C [] düğümleri hariç:

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])") 
+0

Neredeyse bir yıl sonra bunu okuyan herkes bunun sonucunu verdi: http://github.com/boj/kantan-sgf - Dünyadaki en verimli şey değil, ama büyük bir TreeTop/SGF ayrıştı. deney. – bojo

cevap

3
  1. Yapı geliyor SyntaxNodes bir ağaç olarak size dönüş (sonuç nil ise, parser.failure_reason kontrol edin). Bu ağaçta yürüyebilir ya da (ve bu önerilir) istediğiniz şeyi yapan işlevlerle güçlendirebilir ve sadece ana işlevinizi kökte arayabilirsin.

Ne demek istiyorsun "bileşenlere düğüm işlevinden nasıl erişirsiniz?" birkaç yol var.

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 
     } 

Ayrıca şöyle adlandırabilirsiniz:

rule phone_number 
    "(" area_code:(digit digit digit) ")" ... 

ve sonra onlara adıyla bakın Sen eleman [x] gösterimi ile veya kural tarafından onlara alabilirsiniz.

  1. Yalnızca karakterlerle eşleştirmek istiyorsanız, chars kuralı iyi görünüyor. herhangi bir karakterini eşleştirmek istiyorsanız, normal bir ifadede olduğu gibi bir nokta (.) Kullanabilirsiniz.

  2. Sana ayrıştırmak çalıştığınız dil aşina değilim, ama aradığınız kural olabilir bir şey gibi:

rule comment 
    "C" balanced_square_bracket_string 
    end 
rule balanced_square_bracket_string 
    "[" ([^\[\]]/balanced_square_bracket_string)* "]" 
    end 

orta bölümü ikinci kural, köşeli parantez olmayan veya dengeli parantezli yuvalanmış bir dizeyle eşleşen her şeye eşleşir.

P.S.Oldukça aktif bir Google group, çevrimiçi arşivler & aranabilir.

+0

Teşekkürler MarkusQ için teşekkürler. Kafamı buralara sarmaya devam edeceğim, ama doğru yöne gitmemi sağladın. – bojo