我有一个项目,仍然是胚胎,我正在尝试使用真正的语法编写维基解析器。我发现Creole grammar似乎相当完整,并得到了第三方的确认(使用ANTLR)。
我已经开始向前移动,但遇到了一些障碍,我假设有一个常见的绊脚石与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 )+
;
我正在使用Forward,但是对于第二部分,我最终得到了:
OneOrMore(CharsNotIn("=~\r\n") | escaped)('heading_content')
现在这匹配“test”和“test~ =”但不匹配“test~ = foo”,它只匹配“test”部分。那是为什么?
其次我想知道是否有另一种方法来指定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
然而,我的OneOrMore(NotAny(...)| FORCED_LINEBREAK |转义)的天真方法不起作用,最终无限循环。更多地阅读文档表明NotAny实际上并没有返回任何匹配。那么我们如何匹配呢?我不能使用CharNotIn(...),因为单个'{'完全有效。
指针赞赏。答案 0 :(得分:3)
前段时间,我编写了一个用于antlr语法的pyparsing编写的转换器,这可能会有所帮助,我将其作为pyparsing票证中的功能请求提交:
http://sourceforge.net/tracker/index.php?func=detail&aid=3060671&group_id=97203&atid=617314
antlr语法几乎完成,所以它可以完成这项工作,否则,它可能是如何为antlr语法进行pyparsing等效的有用信息的来源,它也包括一些测试。
希望它有所帮助: - )