<p>如果将代码划分为多个函数,每个函数只负责识别一个小功能,例如:</p>
<pre><code>def parse_next_receipe(lines, pos=0):
while 1:
if pos >= len(lines):
break
line = lines[pos]
if line.strip() == ':':
pos, receipe = parse_receipe(lines, pos)
yield receipe # or write it directly to the xml file...
else:
pos += 1
def parse_receipe(lines, pos):
pos, name = parse_name(lines, pos)
pos, description = parse_description(lines, pos)
ingredients = []
while 1:
pos, ingredient = parse_ingredient(lines, pos)
if pos == -1:
break
else:
ingredients.append(ingredient)
return (name, description, ingredients)
def parse_name(lines, pos): ...
def parse_description(lines, pos): ...
def parse_ingredient(lines, pos):
try:
pos, quantity = parse_quantity(lines, pos)
pos, ingredient = parse_ingredientname(lines, pos)
except ValueError:
return -1, None
def parse_quantity(lines, pos):
line = lines[pos]
if line[0] in '0123456789':
# line starts with a number
return pos + 1, line
raise ValueError("Line %r doesn't contain a quantity" % line)
def parse_ingredientname(lines, pos):
line = lines[pos]
if line:
# any non-empty line is ok as an ingredient name
return pos + 1, line
raise ValueError("Expected an ingredient name, found blank line, lineno=%d" % pos)
</code></pre>
<p>这称为递归下降解析。你知道吗</p>
<p>在本例中,每个函数都接受一个<code>pos</code>,这是它应该开始查找的行号,并返回要查找的“next”行+它找到的值。你知道吗</p>
<p>我使用了两种不同的方法来指示解析错误:返回<code>-1</code>作为位置(返回<code>None</code>作为值),或者引发异常。任何一个都是有用的。你知道吗</p>