如何用Rebol PARSE方言表达分支?

Way*_*Cui 5 parsing rebol rebol3

我有一个如下所示的mysql架构:

data: {
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `name` varchar(10) DEFAULT '' COMMENT 'the name',
    `content` text COMMENT 'something',
}
Run Code Online (Sandbox Code Playgroud)

现在我想从中提取一些信息:提交的名称,类型和评论(如果有的话).见下文:

["id" "int" "" "name" "varchar" "the name" "content" "text" "something" ]
Run Code Online (Sandbox Code Playgroud)

我的代码是:

parse data [
    any [ 
        thru {`} copy field to {`} {`}
        thru some space copy field-type to [ {(} | space]
        (comm: "")
        opt [ thru {COMMENT} thru some space thru {'} copy comm to {'}]
        (repend temp field repend temp field-type either comm [ repend temp comm ][ repend temp ""])
    ]
]
Run Code Online (Sandbox Code Playgroud)

但我得到这样的东西:

["id" "int" "the name" "content" "text" "something"]
Run Code Online (Sandbox Code Playgroud)

我知道线路opt ..不对.

我想表达如果找到COMMENT关键字,然后再提取评论信息; 如果首先找到,则继续下一个循环.但我不知道如何表达它.任何人都可以帮忙吗?

rgc*_*ris 5

我非常赞成(在可能的情况下)建立一组带有正项的语法规则来匹配目标输入 - 我发现它更有文化,更精确,更灵活,更容易调试.在上面的代码段中,我们可以确定五个核心组件:

space: use [space][
    space: charset "^-^/ "
    [some space]
]

word: use [letter][
    letter: charset [#"a" - #"z" #"A" - #"Z" "_"]
    [some letter]
]

id: use [letter][
    letter: complement charset "`"
    [some letter]
]

number: use [digit][
    digit: charset "0123456789"
    [some digit]
]

string: use [char][
    char: complement charset "'"
    [any [some char | "''"]]
]
Run Code Online (Sandbox Code Playgroud)

定义了术语,编写描述输入语法的规则相对简单:

result: collect [
    parsed?: parse/all data [ ; parse/all for Rebol 2 compatibility
        opt space
        some [
            (field: type: none comment: copy "")
            "`" copy field id "`"
            space 
            copy type word opt ["(" number ")"]
            any [
                space [
                    "COMMENT" space "'" copy comment string "'"
                    | word | "'" string "'" | number
                ]
            ]
            opt space "," (keep reduce [field type comment])
            opt space
        ]
    ]
]
Run Code Online (Sandbox Code Playgroud)

作为额外的奖励,我们可以验证输入.

if parsed? [new-line/all/skip result true 3]
Run Code Online (Sandbox Code Playgroud)

一点点申请new-line聪明的东西应该产生:

== [
    "id" "int" "" 
    "name" "varchar" "the name" 
    "content" "text" "something"
]
Run Code Online (Sandbox Code Playgroud)