2017-02-08 60 views
0

我想拿出一個PEG語法,將根據的RFC 2396如何在PEG中表達RFC 2396的語法(關於URI)?

hostname  = *(domainlabel ".") toplabel [ "." ] 
    domainlabel = alphanum | alphanum *(alphanum | "-") alphanum 
    toplabel  = alpha | alpha *(alphanum | "-") alphanum 

以下BNF沒有與domainlabeltoplabel沒有問題的解析主機名。

然而,hostname的規則似乎無法在PEG中表達。

這是爲什麼我是這樣認爲的:

如果我們把寫在BNF語法整個輸入由*(domainlabel ".")消耗不知道什麼時候停止,因爲toplabel [ "." ]是從它沒有什麼區別。

簡化自足說明:

h = (d '.')* t '.'? 
d = [dt] 
t = [t] 

這將解析td.d.t和失敗上d.d.d這完全是預期,但它不能解析t.d.d.t.這都是有效的情況下。

如果我們添加一個前瞻,那麼它會消耗t.d.d.t.,但在d.t.t.上失敗。

h = (!(t '.'?)d '.')* t '.'? 
d = [dt] 
t = [t] 

所以我沒有想法,有沒有辦法在PEG中表達這個BNF?

回答

1

如果你只需要檢查的有效性,你可以做這樣的:

/* Unchanged */ 
toplabel  = alpha | alpha *(alphanum | "-") alphanum 
/* Diff with above */ 
nontoplabel = digit | digit *(alphanum | "-") alphanum 
/* Rephrase */ 
hostname  = 1*(*(nontoplabel ".") toplabel) [ "." ] 

由於nontoplabeltoplabel是由他們的第一個字符區分,有中最後一個表達式沒有可能的歧義。

的轉變是許多可能的正則表達式的身份之一:

(a | b)* a ==> (b* a)+ 

您可以隨時與b-a(使用-爲差集運算符)替換ba|b

+0

我對重寫'a | b'的最後一點感興趣。你能給一些參考嗎? – Seki

+0

@seki:這只是簡單的集合論,因爲'|'是兩個集合的聯合。一個集合沒有重複的元素,所以當你計算A和B的聯合時,你可以從B中移除聯合中已經存在的元素,因爲它們在A中。 – rici

+0

感謝你的解釋:) – Seki