1.创建目录结构:
首先创建文件ex49,在ex49中创建skeleton,具体文件如下:
2.parser.py文件中的代码(书中代码):
1 class ParserError(Exception): 2 pass 3 4 class Sentence(object): 5 def __init__(self,subject,verb,object): 6 self.subject=subject[1] 7 self.verb=verb[1] 8 self.object=object[1] 9 10 def peek(word_list): 11 12 if word_list: 13 word=word_list[0] 14 return word[0] 15 else: 17 return None 18 19 def match(word_list,expecting): 20 21 if word_list: 22 word=word_list.pop(0) 23 if word[0]==expecting: 24 25 return word 26 else: 27 return None 28 else: 29 return None 30 31 def skip(word_list,word_type): 32 result='' 33 while peek(word_list)==word_type: 34 result = match(word_list,word_type) 35 return result 36 37 def parse_verb(word_list): 38 skip(word_list,'stop') 39 40 if peek(word_list)=='verb': 41 return match(word_list,'verb') 42 else: 43 raise ParserError("Excepted a verb next") 44 45 def parse_object(word_list): 46 skip(word_list,'stop') 47 next=peek(word_list) 48 49 if next=='noun': 50 return match(word_list,'noun') 51 if next=='direction': 52 return match(word_list,'direction') 53 else: 54 raise ParserError("Excepted a noun or direction next.") 55 56 def parse_subject(word_list,subj): 57 verb=parse_verb(word_list) 58 obj=parse_object(word_list) 59 a=Sentence(subj,verb,obj)
63 return a 64 65 66 def parse_sentence(word_list): 67 skip(word_list,'stop') 68 start=peek(word_list) 69 if start=='noun': 70 subj=match(word_list,'noun') 71 return parse_subject(word_list,subj) 72 73 elif start=='verb': 74 return parse_subject(word_list,('noun','player')) 75 else: 76 raise ParserError("Must start with subject,object,or verb not :%s %start")
3.parse_tests.py中为对parser.py进行单元测试代码(编写代码):
1 from nose.tools import *
2 import sys
3 sys.path.append('H:\\ex49\\skeleton')
4 import ex49.parser
5
6 word_listA=[('verb','kill'),('direction','north')]
7 def test_peek():
8 result=ex49.parser.peek([('verb','kill'),('direction','north')])
9 assert_equal(result,'verb')
10
11 def test_match():
12 result=ex49.parser.match(word_listA,'verb')
13 assert_equal(result,('verb','kill'))
14 assert_equal(word_listA,[('direction','north')])
15 result1=ex49.parser.match(word_listA,'stop')
16 assert_equal(result1,None)
17
18 def test_skip():
19 result=ex49.parser.skip([('verb','kill'),('direction','north')],'verb')
20 assert_equal(result,('verb','kill'))
21
22 def test_parse_verb():
23 result=ex49.parser.parse_verb([('verb','kill'),('direction','north')])
24 assert_equal(result,('verb','kill'))
25 assert_raises(ex49.parser.ParserError,ex49.parser.parse_verb,[('stop','the'),('direction','north')])
26
27
28 def test_parse_object():
29 result=ex49.parser.parse_object([('stop','the'),('noun','door')])
30 assert_equal(result,('noun','door'))
31 result1=ex49.parser.parse_object([('stop','the'),('direction','north')])
32 assert_equal(result1,('direction','north'))
33 assert_raises(ex49.parser.ParserError,ex49.parser.parse_object,[('stop','the'),('verb','go')])
34
35 def test_parse_subject():
36 result=ex49.parser.parse_subject([('verb','go'),('stop','the'),('noun','door')],('m','k'))
37 assert_equal(result.subject,'k')
38 assert_equal(result.verb,'go')
39 assert_equal(result.object,'door')
40
41 def test_parse_sentence():
42 result=ex49.parser.parse_sentence([('verb','go'),('stop','the'),('noun','door')])
43 assert_equal(result.subject,'player')
44 assert_equal(result.verb,'go')
45 assert_equal(result.object,'door')
46
47 result1=ex49.parser.parse_sentence([('stop','in'),('noun','door'),('verb','go'),('direction','north')])
48 assert_equal(result1.subject,'door')
49 assert_equal(result1.verb,'go')
50 assert_equal(result1.object,'north')
51
52 assert_raises(ex49.parser.ParserError,ex49.parser.parse_sentence,[('stop','in'),('stop','the')])
53
4.遇到的问题:
1)从ex49中导入parse.py时,用from ex49 import parse出错
提示ImportError: No module named ex49
发现是同级目录导入文件方式错误,参考http://blog.chinaunix.net/uid-26000296-id-4372344.html文章中第三点
最后更改为以下导入方式才可行:
import sys
sys.path.append('H:\\ex49\\skeleton')
import ex49.parser