2012-08-07 122 views
2

我有一個項目,它仍然是胚胎,我試圖用真正的語法編寫wiki解析器。我發現一個似乎相當完整的Creole grammar,並且被第三方證實可以工作(與ANTLR)。需要幫助將ANTLR語法轉換爲pyparsing

我已經開始向前移動,但是遇到了一些障礙,我假設pyparsing是一個常見的絆腳石。

escaped 
    : ESCAPE STAR STAR 
    | ESCAPE . 
    // '.' in a parser rule means arbitrary token, not character 
    ; 

我想出了這個是:

ESCAPE = Literal('~') 
STAR = Literal('*') 
escaped = ESCAPE + STAR + STAR | ESCAPE + Word(printables, max=1) 

我找不到任何在pyparsing匹配單個字符一樣,但是這似乎工作。但是看標題內容時,我有這個子表達式:

heading_content 
    : heading_markup heading_content (heading_markup)? 
    | (~(EQUAL | ESCAPE | NEWLINE | EOF) | escaped)+ 
    ; 

我使用的是前鋒,但對於第二部分,我結束了:

OneOrMore(CharsNotIn("=~\r\n") | escaped)('heading_content') 

現在這個匹配「測試」和「測試〜=」而不是「測試〜= foo」,它只匹配「測試」部分。這是爲什麼?

其次,我想知道是否有另一種方式來指定除CharsNotIn以外的內容部分?

現在真正讓我難過的一點是試圖匹配未格式化的文本部分。這是匹配各種純文本的核心。現在語法規定:

text_unformatted 
    : (~( ITAL 
     | STAR 
     | LINK_OPEN 
     | IMAGE_OPEN 
     | NOWIKI_OPEN 
     | EXTENSION 
     | FORCED_LINEBREAK 
     | ESCAPE 
     | NEWLINE 
     | EOF) 
    | forced_linebreak 
    | escaped)+ 

這就是我撞牆的地方。現在,上述簡單的位定義爲:

# STAR, ESCAPE and escaped defined above 
ITAL = Literal('//') 
LINK_OPEN = Literal('[[') 
IMAGE_OPEN = Literal('{{') 
NOWIKI_OPEN = Literal('{{{') 
EXTENSION = Literal('@@') 
FORCED_LINEBREAK = Literal(r'\\') 
CR = Literal('\r') 
LF = Literal('\n') 
NEWLINE = Optional(CR) + LF | CR 

但是我的一次或更多的幼稚的方法(NotAny(...)| FORCED_LINEBREAK |轉義)沒有工作,結束了無限循環。多讀一些文檔表明NotAny實際上不會返回任何匹配。那麼我們如何匹配呢?我不能使用CharNotIn(...),因爲一個'{'是完全有效的。

指針讚賞。

回答

3

前一段時間,我寫了寫在pyparsing對ANTLR語法轉換器,這可能是有幫助的,我提交了它作爲pyparsing票功能要求:

http://sourceforge.net/tracker/index.php?func=detail&aid=3060671&group_id=97203&atid=617314

的ANTLR語法是幾乎完全,所以它可能會完成這項工作,否則,它可能是一個有用的信息來源,如何對antlr語法進行pyparsing等價,它也包括一些測試。

希望它可以幫助:-)