Parse函數轉換的語法是?
parse函數轉換的語法主要根據控制流進行改變,提到Rebol語言的優秀特性那就不得不說它的解析引擎,簡稱Parse。這項來自Carl Sassenrath的偉大設計,在過去的15年里,使得Rebol用戶免受正則表達式(以不可維護著稱)的折磨。現如今,Parse的增強版本在Red語言中重裝上陣。
簡而言之,Parse是一個使用語法規則來解析輸入序列的內部DSL(在Rebol生態圈稱為“方言”)。Parse方言是TDPL家族的突出一員。常用來校驗,驗證,分解,修改輸入的數據,甚至是實現內部或者外部DSL。parse函數的用法很簡單:bitset. 實現并支持DSL的發展:parse <輸入序列> <規則> <輸入序列>: 任意序列類型的值(字符串,文件,區塊,路徑...) <規則>: 一個區塊(包含有效的Parse方言)123123
下面的示例代碼可以直接復制到Red控制臺中運行,即便你不懂Red和Parse方言,也能觀其大略,不像正則表達式那樣讓人不知所云。使用語法規則驗證一些字符串和區塊的輸入:parse "a plane" [["a" | "the"] space "plane"] ;規則中可以包含子規則 parse "the car" [["a" | "the"] space ["plane" | "car"]] parse "123" ["1" "2" ["4" | "3"]] parse "abbccc" ["a" 2 "b" 3 "c"] ;指定數量 parse "aaabbb" [copy letters some "a" (n: length? letters) n "b"] ;將匹配綁定到變量,使用小括號執行Red表達式 parse [a] ['b | 'a | 'c] parse [hello nice world] [3 word!] ;匹配區塊可以使用類型 parse [a a a b b b] [copy words some 'a (n: length? words) n 'b]1234567891012345678910
下面展示如何解析IPv4地址:four: charset "01234" ;charset函數用于創建一個bitset!類型的值 half: charset "012345" non-zero: charset "123456789" digit: union non-zero charset "0" ;bitset!類型可以使用Red的集合運算union函數進行組合 byte: [ "25" half | "2" four digit | "1" digit digit | non-zero digit | digit ] ipv4: [byte dot byte dot byte dot byte] parse "192.168.10.1" ipv4 parse "127.0.0.1" ipv4 parse "99.1234" ipv4 parse "10.12.260.1" ipv4 data: { ID: 121.34 Version: 1.2.3-5.6 Your IP address is: 85.94.114.88. NOTE: Your IP Address could be different tomorrow. } parse data [some [copy value ipv4 | skip]] probe value ; 輸出: "85.94.114.88"123456789101112131415161718192021222324252627123456789101112131415161718192021222324252627
一個粗糙然而實用的email地址驗證器:digit: charset "0123456789" letters: charset [#"a" - #"z" #"A" - #"Z"] special: charset "-" chars: union union letters special digit word: [some chars] host: [word] domain: [word some [dot word]] email: [host "@" domain] parse "john@doe.com" email parse "n00b@lost.island.org" email parse "h4x0r-l33t@domain.net" email123456789101112123456789101112
驗證字符串形式的數學表達式(來自Rebol/Core手冊)expr: [term ["+" | "-"] expr | term] ;規則可以遞歸定義 term: [factor ["*" | "/"] term | factor] factor: [primary "**" factor | primary] primary: [some digit | "(" expr ")"] digit: charset "0123456789" parse "1+2*(3-2)/4" expr ; 返回 true parse "1-(3/)+2" expr ; 返回 false1234567812345678
創建簡單的解析器用于解析一個HTML子集:html: { <html> <head><title>Test</title></head> <body><div><u>Hello</u> <b>World</b></div></body> </html> } ws: charset reduce [space tab cr lf] parse html tags: [ collect [any [ ws | "</" thru ">" break | "<" copy name to ">" skip keep (load name) opt tags | keep to "<" ]] ] ; parse函數將會返回如下區塊樹 [ html [ head [ title ["Test"] ] body [ div [ u ["Hello"] b ["World"] ] ] ] ]12345678910111213141516171819202122232425262728293031321234567891011121314151617181920212223242526272829303132
Parse方言,parse/trace <輸入> <規則> <回調函數>
<回調函數> 規格:
func [
event [word!] ; 跟蹤事件
match? [logic!] ; 上次匹配操作的結果
rule [block!] ; 當前位置的對應規則
input [series!] ; 將要匹配的下一個位置的輸入序列
stack [block!] ; 內部的解析規則棧
return: [logic!] ; TRUE: 繼續匹配, FALSE: 退出
]
事件列表:
- push : 當一個規則或者區塊入棧時
- pop : 當一個規則或者區塊出棧之前
- fetch : 當一個新的規則被采用之前
- match : 當一個值匹配發生了
- iterate : 當一個新的迭代開始了 (ANY, SOME, ...)
- paren : 當一個小括號中的表達式被求值后
- end : 當到達輸入末尾時。