我已经完成了非常先进的 Rebol 解析器,它管理实时和关键任务 TCP 服务器,并且需要进行适当的错误报告。所以这很重要!
Rebol 的 PARSE 最独特的方面之一可能是您可以在规则中包含直接评估。所以你可以设置变量来跟踪解析位置,或者错误信息等。   (这很容易,因为 Rebol 的本质是将代码和数据混合为同一个东西是一个核心思想。)  
这就是我的做法。在尝试每个匹配规则之前,我将解析位置保存到“这里”(通过写入here:),然后还使用代码执行将错误保存到变量中(通过放入(error: {some error string})括号以便解析方言运行它)。如果匹配规则成功,我们不需要使用错误或位置......我们只需继续下一条规则。但是如果它失败了,我们将拥有我们设置的最后一个状态,以在失败后报告。
因此,解析方言中的模式很简单:
; use PARSE dialect handling of "set-word!" instances to save parse
; position into variable named "here"
here:
; escape out of the parse dialect using parentheses, and into the DO 
; dialect to run arbitrary code.  Here we run code that saves an error
; message string into a variable named "error"
(error: "<some error message relating to rule that follows>")
; back into the PARSE dialect again, express whatever your rule is,
; and if it fails then we will have the above to use in error reporting
what: (ever your) [rule | {is}]
这基本上就是你需要做的。以下是电话号码的示例:
digit: charset "012345689"
phone-number-rule: [
    here:
    (error: "invalid area code")
    ["514" | "800" | "888" | "916" "877"]
    here:
    (error: "expecting dash")
    "-"
    here:
    (error: "expecting 3 digits")
    3 digit
    here:
    (error: "expecting dash")
    "-"
    here:
    (error: "expecting 4 digits")
    4 digit
    (error: none)
]
然后你可以看到它在行动。请注意,如果我们到达解析规则的末尾,我们将 error 设置为 none。如果还有更多输入要处理,PARSE 将返回 false,所以如果我们注意到没有设置错误但 PARSE 仍然返回 false ......我们失败了,因为有太多额外的输入:
input: "800-22r2-3333"
if not parse input phone-number-rule [
   if none? error [
        error: "too much data for phone number"
    ]
]
either error [
    column: length? copy/part input here newline
    print rejoin ["error at position:" space column]
    print error
    print input
    print rejoin [head insert/dup "" space column "^^"}
    print newline
][
    print {all good}
]
以上将打印以下内容:
error at position: 4
expecting 3 digits
800-22r2-3333
    ^
显然,您可以做更有效的事情,因为您放入括号中的任何内容都将像正常的 Rebol 源代码一样被评估。它真的很灵活。我什至有在加载大量数据集时更新进度条的解析器...... :-)