2011-03-03 50 views
3

這是一個既針對parboiled解析器框架又針對BNF/PEG的問題。EBNF/parboiled:如何將regexp翻譯成PEG?

比方說,我有相當簡單的正則表達式

^\\s*([A-Za-z_][A-Za-z_0-9]*)\\s*=\\s*(\\S+)\\s*$ 

代表的

<line>    ::= <ws>? <identifier> <ws>? '=' <nonwhitespace> <ws>? 
<ws>     ::= (' ' | '\t' | {other whitespace characters})+ 
<identifier>   ::= <identifier-head> <identifier-tail> 
<identifier-head> ::= <letter> | '_'  
<identifier-tail> ::= (<letter> | <digit> | '_')* 
<letter>    ::= ('A'..'Z') | ('a'..'z') 
<digit>    ::= '0'..'9' 
<nonwhitespace>  ::= ___________ 

你如何定義非空白(即沒有空格的一個或多個字符)的僞EBNF在EBNF?

對於那些熟悉Java快煮庫的人,你如何實現一個定義非空白的規則?

+0

等待,在哪裏重複量詞?據我可以閱讀的語法只能有一個字母等 – fge

+0

請參閱'標識符尾巴' –

+0

呃,好吧,我試圖讀它作爲一個EBNF文法,其中'*'會在paren之前。 。 – fge

回答

5

你一直用你的詞法生成器的約定來指定字符範圍和字符範圍的操作。

許多詞法分析器發電機接受十六進制值(類似0X)來表示字符,所以你可能會這樣寫:

'0'..'9' 
0x30..\0x39 

的數字。

對於非空白空間,您需要知道您正在使用哪個字符集。對於7位ASCII,非空白是概念上的所有打印字符:

0x21..\0x7E 

對於ISO8859-1:

(0x21..\0x7E | 0x80-0xFF) 

你可以自己決定,如果上述0x80的字符代碼空間或沒有(非 - 休息空間的空間?)。您還可以決定控制字符0x0..0x1F的狀態。選項卡(0x9)是否爲空白字符? CR 0xD和LF 0xA如何? ETB控制角色如何?

Unicode很難,因爲它的一個巨大的設置,並且你的列表變得很大和混亂。 C'est la vie。我們的DMS Software Reengineering Toolkit用於構建各種語言的解析器,並且必須支持用於ASCII的詞法分析器,用於大量z和Unicode的ISO8859-z。而不是編寫複雜的「添加劑」正則表達式範圍內,DMS允許消減正則表達式,所以我們可以這樣寫:

<UniCodeLegalCharacters>-<UniCodeWhiteSpace> 

這是很容易理解和得到它的權利在第一次嘗試。

2

在EBNF我會簡單地定義爲非空白,是不是空白的任何字符:

nonwhitespace ::= anycharacter - whitespace 

這需要你有一個「anycharacter」字面定義可能的符號的整個範圍,並明確定義其中的字符是空格。

在蒸穀米您可以在此使用TestNotANY規則,因此,例如 非空白將被定義爲不匹配空白()條的任何字符做:

Sequence(TestNot(WhiteSpace()) , ANY)