3

我目前正在尝试编写 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[] 节点:

例子.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])")
4

1 回答 1

3
  1. 该结构以 SyntaxNodes 树的形式返回给您(如果结果为 nil,请检查 parser.failure_reason)。您可以遍历这棵树,或者(这是推荐的)您可以使用执行您想要的功能的函数来扩充它,并且只需在根上调用您的 main 函数。

如果您的意思是“如何从节点函数中访问组件?” 有几种方法。您可以使用 element[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. 如果您只想匹配这些字符,您的 chars 规则看起来不错。如果您想匹配任何字符,您可以像在正则表达式中一样使用点 (.)。

  2. 我不熟悉您尝试解析的语言,但您正在寻找的规则可能类似于:

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

第二条规则的中间部分匹配任何不是方括号或带有balanced_square 括号的嵌套字符串的内容。

PS 有一个相当活跃的谷歌群组,有在线存档和可搜索的。

于 2009-02-28T02:58:50.903 回答