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