<p>在四处探访了一下之后,我发现<a href="http://pyparsing.wikispaces.com/message/view/home/11262229" rel="nofollow noreferrer">this help thread</a>那里有一个值得注意的地方</p>
<blockquote>
<p>I often see inefficient grammars when
someone implements a pyparsing grammar
directly from a BNF definition. BNF
does not have a concept of "one or
more" or "zero or more" or
"optional"...</p>
</blockquote>
<p>这样,我就有了改变这两条线的想法</p>
<pre><code>multi_line_word = Forward()
multi_line_word << (word | (split_word + multi_line_word))
</code></pre>
<p>到</p>
^{2}$
<p>这让它输出了我想要的:<code>['super', 'cali', fragi', 'listic']</code>。在</p>
<p>接下来,我添加了一个parse操作,它将把这些标记连接在一起:</p>
<pre><code>multi_line_word.setParseAction(lambda t: ''.join(t))
</code></pre>
<p>这将给出<code>['supercalifragilistic']</code>的最终输出。在</p>
<p>我学到的一条信息是,一个人不仅仅是<a href="http://waxy.org/random/images/weblog/mortor.gif" rel="nofollow noreferrer">walk into Mordor</a>。在</p>
<p>开玩笑而已。在</p>
<p>主要的信息是,不能简单地用pyparsing实现BNF的一对一转换。应该调用一些使用迭代类型的技巧。在</p>
<p><strong>编辑2009年11月25日:</strong>为了补偿更复杂的测试用例,我将代码修改为以下代码:</p>
<pre><code>no_space = NotAny(White(' \t\r'))
# make sure that the EOL immediately follows the escape backslash
continued_ending = Literal('\\') + no_space + lineEnd
word = Word(alphas)
# make sure that the escape backslash immediately follows the word
split_word = word + NotAny(White()) + Suppress(continued_ending)
multi_line_word = OneOrMore(split_word + NotAny(White())) + Optional(word)
multi_line_word.setParseAction(lambda t: ''.join(t))
</code></pre>
<p>这样做的好处是确保任何元素之间没有空格(转义反斜杠后面的换行符除外)。在</p>