Perl 6 中的正則表達(dá)式(四)

最長 token 匹配

注意伯顶,下面進(jìn)入糟糕區(qū)域,如果看不懂請查看英文原文!

S05-metasyntax/longest-alternative.t lines 53–460

因?yàn)?"longest-token matching" 是一個(gè)很長的短語, 我們會經(jīng)常將這個(gè)概念叫做 LTM. 這個(gè)基本的概念就是人們在頭腦中傾向于怎么去解析文本, 所以計(jì)算機(jī)應(yīng)該像人一樣嘗試做同樣的事情. 而使用 LTM 解析文本就是關(guān)于計(jì)算機(jī)怎樣決定匹配一組備選分支中的哪一個(gè)備選分支的.

在 Perl 6 中, | 代表使用聲明性的 longest-token 語義的邏輯備選分支.(你現(xiàn)在能使用 || 來標(biāo)示舊的暫存的備選分支. 就是, ||| 現(xiàn)在在正則語法內(nèi)的運(yùn)作方式和在正則語法外的運(yùn)作方式很像, 在正則語法外部, ||| 代表 junctional 和 短路的 OR. 這也包括事實(shí)上 | 的優(yōu)先級比 || 的優(yōu)先級高.)

在過去, Perl 中正則表達(dá)式是通過一個(gè)能回溯的 NFA 算法來處理的. 這很強(qiáng)大, 但是很多解析器通過并行地處理 rules , 而不是一個(gè)接著一個(gè)地處理, 工作起來更高效, 至少達(dá)到某種程度. 如果你看一下像 yacc grammar 這樣的東西, 你會發(fā)現(xiàn)很多 pattern/action 聲明, 其中的 patterns 被認(rèn)為是并行的, 并且最終由 grammar 決定觸發(fā)哪個(gè) action. 雖然默認(rèn)的Perl 解析角度是從上至下的(或許使用一個(gè)中間層的從下至上角度來處理操作符優(yōu)先級), 這對用戶理解 token 處理進(jìn)行確定性很有用。所以, 為了 regex 匹配的意圖, 我們把 tokens 模式定義為那些不含潛在副作用或自引用的能被匹配的模式。(因?yàn)榭崭裨谛修D(zhuǎn)換時(shí)經(jīng)常有副作用, 所以通常被這樣的模式排除, 給予或采取一點(diǎn)向前查看。) 基本上, Perl 自動地從 grammar 中派生出一個(gè)詞法分析程序, 而不需要你自己寫一個(gè)垢油。

為此, Perl 6 中的每個(gè) regex 被要求能把它的純模式和它的 actions 區(qū)分開, 并返回它的初始 token 模式的列表(包含由regex 的純部分調(diào)用的 subrule 的 token 模式, 但是不包含多于一次的 subrule, 因?yàn)槟强赡軙鹱砸? 這在傳統(tǒng)正則表達(dá)式中是不被允許的。) 一個(gè)使用|的邏輯備選分支接收兩個(gè)或多個(gè)這種列表并分發(fā)給匹配最長 token 前綴的備選分支圆丹。出現(xiàn)在第一位的可能是也可能不是那個(gè)備選分支滩愁。

然而, 如果兩個(gè)備選分支以同樣的長度匹配, 綁定首先由特異性打破。 以最長的固定字符串開頭的備選分支勝出; 即一個(gè)精確的匹配被看作是比使用字符類更接近. 如果它不起作用, 綁定會由兩個(gè)方法中的一個(gè)破壞. 如果備選分支在不同的 grammars 中, 那么標(biāo)準(zhǔn)的 MRO(方法解析順序)決定首先嘗試哪一個(gè). 如果備選分支在同一個(gè) grammar 文件中, 本文出現(xiàn)的更早的備選分支取得優(yōu)先權(quán). (如果一個(gè) grammar 的 rules 被定義在不止一個(gè)文件中, 那么順序是未定義的, 則必須使用一個(gè)顯式的斷言用于強(qiáng)制失敗, 如果首先嘗試錯(cuò)誤的那個(gè)的話)

這個(gè)長的標(biāo)記前綴大致相當(dāng)于“令牌”在其他分析系統(tǒng)使用一個(gè)詞法分析器的概念辫封,但對于Perl這很大程度上是自動從語法定義一個(gè)偶然現(xiàn)象硝枉。然而,盡管是自動計(jì)算的倦微,這一套標(biāo)記可以由用戶修改妻味;各種內(nèi)構(gòu)造正則表達(dá)式的語法來告訴引擎,這是完成圖案的部分開始的副作用欣福,所以將這種構(gòu)建用戶控件被認(rèn)為是象征性的责球,什么是不。被視為終止一個(gè)令牌聲明并啟動“行動”部分的結(jié)構(gòu)的結(jié)構(gòu)包括:
這種最長 token 前綴大致相當(dāng)于在其它解析系統(tǒng)中使用詞法解析程序的 "token" 標(biāo)記, 但對于 Perl 這很大程度上是從 grammar 定義中派生的附帶現(xiàn)象拓劝。然而雏逾,盡管是自動計(jì)算的, 這套 tokens 可以由用戶修改; regex 中的各種結(jié)構(gòu)聲明性的告訴 grammar 引擎, 模式部分結(jié)束, 并開始進(jìn)入副作用, 所以通過插入這樣的結(jié)構(gòu), 用戶控制什么是 token, 什么不是。終止 token 聲明并開始模式的 "action" 部分的結(jié)構(gòu)包括:

  • 任何 :: 或 ::: 回溯控制 (而不是e : 肯定修飾符).
  • 任何帶有節(jié)儉匹配(使用 ?修飾符)量詞化的原子郑临。
  • 任何 {...} action, 但不是含有閉包的斷言栖博。(空的閉包 {} 通常用于顯式地終止模式的 pure 部分。) 一般的 **{...} 量詞形式的閉包也會終止最長 token, 但是無閉包形式的量詞不會厢洞。
  • 任何諸如 ||&& 按次序的控制流操作符.
  • 作為前一點(diǎn)的結(jié)果仇让,因?yàn)闃?biāo)準(zhǔn)的 grammar 規(guī)則使用 || 定義空格, 最長的token 也由那 可能 使用那個(gè)規(guī)則匹配空格的 regex 或 rule 的任意部分終止, 包括通過 :sigspace隱式匹配的空格。(然而犀变,token 聲明明確允許通過在 token 中使用諸如 \h+ 或其它字符類這種低級原語來識別空格)
  • Subpatterns(捕獲)不終止token模式妹孙,但可能需要重新解析 token以找到Subpatterns的位置。同樣地获枝,在確定最長token之后斷言可能需要被檢查蠢正。(或者, 如果以任何一種方式模仿了 DFA 語義, 例如, 使用湯普森的NFA,可能可以知道什么時(shí)候觸發(fā)斷言而不使用backchecks省店。)

貪婪量詞和字符類不會終止 token 模式嚣崭。 諸如單詞邊界的零寬斷言也不會。

因?yàn)檫@種斷言可以是 token 的一部分, 詞法分析程序引擎必須能從這種斷言的失敗中恢復(fù), 并回溯到下一個(gè)最佳 token 候選者, 它可能等長或更短, 但是絕對不會當(dāng)前候選者更長懦傍。

對于含有諸如 <?foo><?before \s> 這樣的正向向前查看的模式, 這種斷言會被認(rèn)為比隨后的模式更特殊, 所以向前查看的模式被當(dāng)作最長 token 的最后一部分; 最長 token 匹配器會足夠智能地把額外的 bit 當(dāng)作是零寬的, 即, 重新匹配任何由向前查看遍歷到的文本,當(dāng)它(如果)繼續(xù)匹配的時(shí)候雹舀。(實(shí)際上, 如果整個(gè)向前查看足夠純粹地參與 LTM, 再匹配可能僅僅優(yōu)化掉 rematching, 因?yàn)橄蚯安榭匆呀?jīng)在 LTM 引擎中匹配過了)

然而, 對于包含諸如 <!foo><!before \s> 這種否定向前查看斷言的模式, 反面的才是真: 隨后的模式被認(rèn)為比該斷言更特殊。所以 LTM 完全忽略了否定向前查看, 并繼續(xù)從跟在否定向前查看后面的任何東西中查找純粹模式粗俱。你可能會說, 正向向前查看對 LTM 是不透明的, 否地向前查看對 LTM 是透明的说榆。 結(jié)論是,如果你想寫一個(gè)對 LTM 是透明的正向向前查看, 你可以使用兩個(gè)感嘆號的否定: <!!foo> 來標(biāo)示它。(優(yōu)化器能自由地移除雙否定, 但是不是透明性)。

奇怪的是签财,這 令牌 關(guān)鍵詞具體不確定一個(gè)令牌的范圍串慰,除了一個(gè)令牌模式通常不匹配的空白,而空白是終止令牌的典型方式唱蒸。
很奇怪, token 關(guān)鍵字不確定 token 的作用域, 除了作為一個(gè) token 模式通常不做很多的空格匹配情況之外, 空格是終止 tokens 的原型方式邦鲫。

初始token匹配器必須把區(qū)分大小寫考慮在內(nèi)(或任何其他規(guī)范化原語)并做正確的事, 即使傳播到不具有相同的規(guī)范化的 rules 時(shí)。也就是說神汹,它們必須繼續(xù)代表較低規(guī)則能匹配的一組匹配庆捺。

|| 形式有舊的短路語義,而不會試圖匹配其右側(cè), 除非它的左側(cè)耗盡了所有的可能性(包括所有 | 可能性)屁魏。regex 中的第一個(gè) || 讓它左側(cè)的 token 模式能從外部的最長 token 匹配器中訪問, 但從最長 token 匹配隱藏的任何后續(xù)的測試滔以。每一個(gè) ||建立了一個(gè)新的最長 token匹配器。那就是, 如果你在 || 右側(cè)使用 |蚁堤,那么右側(cè)為最長 token 處理這子表達(dá)式和任何被調(diào)用的 subrules建立了一個(gè)新的頂級作用域處理這個(gè)子表達(dá)式和任何所謂的規(guī)則醉者。右邊的最長 token 自動機(jī)是對于左側(cè)的 || 或外部的含有 || 的 regex是不可見的。

大西瓜啊披诗,翻譯的狗屎一樣撬即,慘不忍睹!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末呈队,一起剝皮案震驚了整個(gè)濱河市剥槐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌宪摧,老刑警劉巖粒竖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異几于,居然都是意外死亡蕊苗,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進(jìn)店門沿彭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來朽砰,“玉大人,你說我怎么就攤上這事喉刘∏迫幔” “怎么了?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵睦裳,是天一觀的道長造锅。 經(jīng)常有香客問我,道長廉邑,這世上最難降的妖魔是什么哥蔚? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任倒谷,我火速辦了婚禮,結(jié)果婚禮上肺素,老公的妹妹穿的比我還像新娘恨锚。我一直安慰自己宇驾,他們只是感情好倍靡,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著课舍,像睡著了一般塌西。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上筝尾,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天捡需,我揣著相機(jī)與錄音,去河邊找鬼筹淫。 笑死站辉,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的损姜。 我是一名探鬼主播饰剥,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼摧阅!你這毒婦竟也來了汰蓉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤棒卷,失蹤者是張志新(化名)和其女友劉穎顾孽,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體比规,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡若厚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蜒什。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片测秸。...
    茶點(diǎn)故事閱讀 39,688評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖吃谣,靈堂內(nèi)的尸體忽然破棺而出乞封,到底是詐尸還是另有隱情,我是刑警寧澤岗憋,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布肃晚,位于F島的核電站,受9級特大地震影響仔戈,放射性物質(zhì)發(fā)生泄漏关串。R本人自食惡果不足惜拧廊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望晋修。 院中可真熱鬧吧碾,春花似錦、人聲如沸墓卦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽落剪。三九已至睁本,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間忠怖,已是汗流浹背呢堰。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留凡泣,地道東北人枉疼。 一個(gè)月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像鞋拟,于是被迫代替她去往敵國和親骂维。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容