Perl 6 中 token 和 rule 的區(qū)別

在 grammar 中, 有兩個 regex 的變體, ruletoken。rule 默認不會回溯. rule 與 token 的一個重要區(qū)別就是, rule 這樣的正則采取了 :sigspace 修飾符。 rule 實際上是

    regex :ratchet :sigspace { ... }

的簡寫. ratchet 這個單詞的意思是: (防倒轉(zhuǎn)的)棘齒, 意思它是不能回溯的! 而 :sigspace 表明正則中的空白是有意義的, 而 token 實際上是

    regex :ratchet { ... }

的簡寫。 所以在 token 中, 若不是顯式的寫上 \s、\h\n 等空白符號, 其它情況下就好像空白隱身了一樣, 雖然你寫了, 但是編譯器卻視而不見。

use v6;
use Grammar::Debugger;
grammar Token::Rule::Difference {
    # 下面三者等價
    # rule TOP { [\w+]+ % ' ' | [\d+]+ % ' '   }  等價于
    # rule TOP { | [\w+]+ % ' ' | [\d+]+ % ' ' }  等價于
    rule TOP { | [\w+]+ % ' '
               | [\d+]+ % ' '
             }
}

# $=finish.lines 中的每一行末尾都沒有換行符
for $=finish.lines -> $line {
    print($line);
    say Token::Rule::Difference.parse($line)
}

=finish
token takes whitespace invisible unless with sigspace
rule is a token without sigspace
2015 12 25
2016 01 07

說明在 rule 中, | 左右兩邊的空格會被忽略, 這通常是為了使格式對齊, 看起來不亂。另外 rule 中, 開頭和末尾的空白也會被忽略。

如果每一行都帶有換行符呢?

use v6;
use Grammar::Debugger;
grammar Token::Rule::Difference {

    # token TOP { ^ [<line>\n]+ $ }
    # token line {
    #     | [\w+]+ % ' '
    #     | [\d+]+ % ' '
    # }

# 等價于

    rule TOP { ^ <wrap>+ $}
    token wrap { <line> }
    rule line {
         [\w+]+ % ' ' | [\d+]+ % <[-\s:]>
    }
}

my $str = q:to/EOF/;
token takes whitespace invisible unless with sigspace
rule is a token without sigspace
2015-12-25 12:23
2016-01-07 13:45
EOF

my $parse = Token::Rule::Difference.parse($str);
say $parse;

token vs. rule


When we use rule in place of token, any whitespace after anatom is turned into a non-capturing call to ws

這句話是說, 在 rule 中, 任何跟在原子(atom)后面的空白會變成非捕獲的ws調(diào)用, 即 <.ws>,

rule entry { <key> '=' <value> }

等價于:

token entry { <key> <.ws> '=' <.ws> <value> <.ws> } # .抑制了捕獲

在 grammar 中, 我們繼承了默認的 ws, 但是我們也可以提供自己的 ws:

token ws { \h* } # 匹配水平空白, 不包括換行

rule 中空白的使用:

my $str = "Swift          is hard    to  learn";
my token word { \w+ }
my rule  line { <word>+ % [',' ] }
$str ~~ m:g/ <line> /;

逗號附近的方括號保證了 <.ws> 調(diào)用產(chǎn)生的空白作為分割符的一部分。這利用了 <.ws> 的一個特點:

在兩個 \w 之間解釋為 \s+, 其它地方解釋為 \s*。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容