我有一個項目,它仍然是胚胎,我試圖用真正的語法編寫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(...),因爲一個'{'是完全有效的。
指針讚賞。