Raku 程式設計/語法
正則表示式本身很有用,但有限制。重用正則表示式可能很困難,將它們分組到邏輯塊中也很困難,並且從一個塊繼承正則表示式非常困難。這就是語法發揮作用的地方。語法與正則表示式之間的關係,就像類與資料和程式碼例程之間的關係。語法允許正則表示式像程式語言的普通一等公民一樣行事,並利用類系統的強大功能。語法可以像類一樣繼承和過載。事實上,Raku 語法本身可以被修改,以便在執行時向語言新增新功能。我們將在後面看到這些示例。
語法被分解為稱為規則、標記和原型的元件。標記就像我們已經見過的正則表示式。規則就像子例程,因為它們可以呼叫其他規則或標記。原型就像預設的多子例程,它們定義了一個可以被覆蓋的規則原型。
標記是不回溯的正則表示式,這意味著如果表示式的一部分已匹配,則即使它阻止表示式更大的一部分匹配,這部分也不會被改變。雖然這犧牲了正則表示式的一些靈活性,但它允許以更高效的方式建立更復雜的解析器。
token number {
\d+ ['.' \d+]?
}
規則是將標記和其他規則組合在一起的方式。所有規則都將被賦予名稱,並且可以使用< > 尖括號引用同一語法中的其他規則或標記。與標記一樣,它們也不回溯,但它們內部的空格將按字面解釋,而不是被忽略。
rule URL {
<protocol>'://'<address>
}
此規則匹配一個 URL 字串,其中包含像 "ftp" 或 "https" 這樣的協議名稱,後面跟著文字元號 "://",然後是一個表示地址的字串。此規則依賴於兩個子規則,<protocol> 和 <address>。它們可以定義為標記或規則,只要它們在同一個語法中。
grammar URL {
rule TOP {
<protocol>'://'<address>
}
token protocol {
'http'|'https'|'ftp'|'file'
}
rule address {
<subdomain>'.'<domain>'.'<tld>
}
...
}
原型定義了一種規則或標記型別。例如,我們可以定義一個原型標記 <protocol>,然後定義幾個表示不同協議的標記。在一個標記中,我們可以將它的名稱引用為 <sym>
grammar URL {
rule TOP {
<protocol>'://'<address>
}
proto token protocol {*}
token protocol:sym<http> {
<sym>
}
token protocol:sym<https> {
<sym>
}
token protocol:sym<ftp> {
<sym>
}
token protocol:sym<ftps> {
<sym>
}
...
}
這相當於說
token protocol {
<http> | <https> | <ftp> | <ftps>
}
token http {
http
}
...
但是更具可擴充套件性,允許以後指定協議型別。例如,如果我們想定義一種新的 URL 型別,它也支援 "spdy" 協議,我們可以使用
grammar URL::WithSPDY is URL {
token protocol:sym<spdy> {
<sym>
}
}
一旦我們擁有了上面定義的語法,我們就可以使用 .parse 方法來匹配它
my Str $mystring = "http://www.wikibooks.org";
if URL.parse($mystring) {
#if it matches a URL, do something
}
匹配物件是一種特殊的 資料型別,它表示語法的解析狀態。當前的匹配物件儲存在特殊變數 $/ 中。
透過將語法與解析器操作類組合,可以將語法轉換為互動式解析器。當語法匹配某些規則時,可以使用當前匹配物件呼叫相應的操作方法。