parsing - 如何解析函数参数 block ?

标签 parsing rebol

我想重新组织给定 Rebol 函数中的参数 block ,以便更容易理解该函数所需的参数。 Rebol 函数中的参数 block 是 Rebol 中可延展数据结构的一个很好的例子:

adjoin: func [
    "Adjoins"
    series [series!] "Series to adjoin"
    joinee
    /local other
][...]

但我需要一些更可预测的东西来理解这些元数据。我如何将其转换为更兼容的格式?一个例子:

[
    ; should include about value whether the about string is there or not
    about none none "Adjoins"
    argument series [series!] "Series to Adjoin"
    argument joinee none none
    option local none none
    argument other none none
]

对转换方法或表示参数内容的最佳方式的任何想法都会非常有帮助。

最佳答案

这是一个完整的 rebol 脚本,应该可以帮助您:-)

请注意,变量不必以点开头,解析规则也不需要用 = 符号括起来。这是一种在规则内分离每件事的任务的快速方法。这样可以更容易地识别哪个单词做什么,当您开始构建更大的规则时,这一点尤其重要。

rebol [
    title: "func spec extractor"
]



code: {adjoin: func [
    "Adjoins"
    series [series!] "Series to adjoin"
    joinee
    /local other
][...]

append: func [
    {Appends a value to the tail of a series and returns the series head.}
    series [series! port!]
    value
    /only "Appends a block value as a block"
][ ... ]
}



code: load code

;----
; setting to a temp variable, prevents .param-str from being erased 
; if the rule doesn't match at the point the rule is used (it may be optional)
;----
=param-str=: [set .tmp string! (.param-str: .tmp)] 
=param-types=: [set .tmp into [some [word!]] (.param-types: .tmp)] 

=param=: [
    (.param-types: .tmp: .param-str: none )
    set .param-name word!
    opt =param-str= 
    opt =param-types= 
    opt =param-str=
    ( 
        append/only .param-blk .tmp: reduce [ .param-name .param-str .param-types ]
    )
]

=refinements=: [
    (.ref-str: none)
    set .refinement refinement! 
    opt [ set .ref-str string! ]
    (
        append .param-blk .refinement
        append .param-blk .ref-str
    )    
    any =param=
]

=func-rule=: [
    ; set/reset variables
    (
        func-def: context [name: none doc-str: none args: [] refinements: [] code: none]
        .tmp: .func-name: .doc-str: .param-str: none
    )

    set .func-name set-word!  
    'func into [
        opt [ set .doc-str string! ]
        ( func-def/args:  .param-blk: copy [] )
        any =param=
        ( func-def/refinements:  .param-blk: copy [] )
        any =refinements=
        here:        
    ]
    set .func-body block!
    (
        func-def/name:    .func-name
        func-def/doc-str: .doc-str
        func-def/code:    .func-body
    )
]      

funcs: []
parse code [ some [ =func-rule=  ( append funcs func-def) | skip ]]

probe funcs

这是它打印出来的内容:

[make object! [
        name: adjoin:
        doc-str: "Adjoins"
        args: [[
                series "Series to adjoin" [series!]
            ] [
                joinee none none
            ]]
        refinements: [
            /local none [other none none]
        ]
        code: [...]
    ] make object! [
        name: append:
        doc-str: {Appends a value to the tail of a series and returns the series head.}
        args: [[
                series none [series! port!]
            ] [
                value none none
            ]]
        refinements: [
            /only "Appends a block value as a block"
        ]
        code: [...]
    ]]

关于parsing - 如何解析函数参数 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17707073/

相关文章:

python - SQL 请求无法使用 sqlparse 进行正确解析

python 文件操作(bash 脚本移植)

parsing - 为什么静态解析器生成器比动态解析器​​生成器更普遍?

parsing - 如何使用 Red 或 Rebol 解析和翻译 DSL

java - 拆分 Java 字符串

java - 是否存在不以完整解析为目标的选区解析器?

rebol - r3-gui 无法输入中文拼音

file-io - 在 Rebol 中,如何复制文件而不将其加载到内存中?

rebol - 如何在 MSVC 中构建 Rebol 3

windows - 如何去掉rebol脚本安全级别提示