Treetop SGF Парсинг - PullRequest
       21

Treetop SGF Парсинг

3 голосов
/ 28 февраля 2009

В настоящее время я пытаюсь написать грамматику Treetop для анализа файлов простого игрового формата, и пока она в основном работает. Однако есть несколько вопросов, которые возникли.

  1. Я не уверен, как на самом деле получить доступ к структуре, которую Treetop генерирует после разбора.
  2. Есть ли лучший способ обработки захвата всех символов, чем правило моего символа?
  3. Есть случай для комментариев, которые я не могу написать правильно.

    C [player1 [4k \]: привет player2 [3k \]: привет!]

Я не могу обернуть голову, как справиться с вложенной структурой узла C [] с [] внутри них.

Это мой текущий прогресс.

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

И мой тестовый пример, в настоящее время исключающий узлы C [] с вышеупомянутой проблемой вложенных скобок:

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

1 Ответ

3 голосов
/ 28 февраля 2009
  1. Структура возвращается к вам в виде дерева синтаксических узлов (если результат равен нулю, проверьте parser.failure_reason). Вы можете пройтись по этому дереву или (и это рекомендуется) вы можете дополнить его функциями, которые делают то, что вы хотите, и просто вызываете вашу основную функцию в корне.

Если вы имеете в виду "как получить доступ к компонентам из функции узла?" Есть несколько способов. Вы можете получить их с помощью элемента [x] или по правилу:

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
       }

Вы также можете назвать их так:

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

и затем обратитесь к ним по имени.

  1. Ваше правило для символов выглядит отлично, если вы хотите сопоставить только этих персонажей. Если вы хотите сопоставить любой символ , вы можете просто использовать точку (.), Как в регулярном выражении.

  2. Я не знаком с языком, который вы пытаетесь разобрать, но правило, которое вы ищете, может выглядеть примерно так:

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

Средняя часть второго правила соответствует всему, что не является квадратной скобкой или вложенной строкой с сбалансированными квадратными скобками.

P.S. Существует довольно активная группа Google , с архивами в Интернете и возможностью поиска.

...