Pergunta

Atualmente, estou tentando escrever uma gramática Treetop para analisar arquivos de formato simples jogo, e tê-lo na sua maioria trabalhando até agora. No entanto, existem algumas questões que têm surgido.

  1. Não tenho a certeza como realmente acessar a estrutura Treetop gera após uma análise.
  2. Existe uma maneira melhor de lidar com a captura de todos os caracteres do que os meus caracteres governar?
  3. Há um caso para comentários que eu não consigo escrever corretamente.

    C [player1 [4k \]: player2 oi [3k \]: oi]

Eu não posso envolver minha cabeça em torno de como lidar com a estrutura aninhada do C [] nó com [] 's dentro deles.

O seguinte é o meu progresso atual.

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 o meu caso de teste, atualmente excluindo C [] nós com o acima mencionado problema suporte aninhada:

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])")
Foi útil?

Solução

  1. A estrutura vem de volta para você como uma árvore de SyntaxNodes (se o resultado é nulo, parser.failure_reason cheque). Você pode andar esta árvore ou (e isso é recomendado), você pode aumentá-la com funções que fazer o que quiser e apenas chamar a sua função principal na raiz.

Se o que você quer dizer é "como você acessar os componentes de dentro de uma função nó?" existem várias maneiras. Você pode chegar a eles com o elemento de notação [x] ou pela regra:

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
       }

Você também pode nomeá-los assim:

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

e, em seguida, se referir a eles pelo nome.

  1. Seus caracteres governar aparência bem se você só quer combinar esses caracteres. Se você deseja corresponder qualquer personagem que você pode usar apenas um ponto (.) Como em uma expressão regular.

  2. Eu não estou familiarizado com o idioma que você está tentando analisar, mas a regra que você está procurando pode ser algo como:

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

A parte do meio da segunda regra corresponde a qualquer coisa que não é um colchete ou uma seqüência aninhada com suportes balanced_square.

P.S. Há um grupo Google bastante ativa , com arquivos on-line e pesquisável.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top