一 实战
1 ex49.py
# -*- coding: utf-8 -*-
class ParserError(Exception):
pass
class Sentence(object):
#subject, verb, object都是二元组,第一元是词的类型,第二元是词的含义
def __init__(self, subject, verb, object):
self.subject = subject[1]
self.verb = verb[1]
self.object = object[1]
#返回单词列表首个单词的词的类型
def peek(word_list):
if word_list:
word= word_list[0]
return word[0]
else:
return None
#如果匹配了,返回单词列表的首个词的二元组,word_list弹出了首个单词
def match(word_list, expecting):
if word_list:
word = word_list.pop(0)
if word[0] == expecting:
return word
else:
return None
else:
return None
#跳过单词列表中的stop
def skip(word_list, word_type):
while peek(word_list) == word_type:
match(word_list, word_type)
#返回谓语,word_list去掉动词
def parse_verb(word_list):
skip(word_list, 'stop')
if peek(word_list) == 'verb':
return match(word_list, 'verb')
else:
raise ParserError("Expected a verb next.")
#返回宾语,word_list去掉宾语
def parse_object(word_list):
skip(word_list, 'stop')
next = peek(word_list)
if next == 'noun':
return match(word_list, 'noun')
if next == 'direction':
return match(word_list, 'direction')
else:
raise ParserError("Expected a noun or direction next.")
#返回主语,word_list去掉主语
def parse_subject(word_list):
skip(word_list, 'stop')
next_word = peek(word_list)
if next_word == 'noun':
return match(word_list, 'noun')
elif next_word == 'verb': #如果是动词,则主语默认是player
return ('noun', 'player')
else:
raise ParserError("Expected a verb next.")
def parse_sentence(word_list):
subj = parse_subject(word_list)
verb = parse_verb(word_list)
obj = parse_object(word_list)
return Sentence(subj, verb, obj)
2 ex49_tests.py
#coding:utf-8
from nose.tools import *
from ex49.ex49 import *
# 输入nosetests,开始测试一个
def test_Sentence():
sentence = Sentence(('noun', 'apple'), ('verb', 'eat'), ('direction', 'good'))
assert_equal(sentence.subject, 'apple')
def test_peek():
#sentence = Sentence(('noun', 'apple'), ('verb', 'eat'), ('direction', 'good'))
peek1 = peek([('noun', 'apple'), ('verb', 'eat'), ('direction', 'good')])
peek2 = peek([('direction', 'good')])
peek3 = peek([])
assert_equal(peek1, 'noun')
assert_equal(peek2, 'direction')
assert_equal(peek3, None) # None != 'None'
def test_match():
match1 = match([('verb', 'eat'), ('noun', 'apple')], 'verb') #match接收的是word_list
assert_equal(match1, ('verb', 'eat'))
# 我觉得的parse_verb()方法不是需要测试——因为它还调用了别的方法(不知道我想的对不对)
#def test_parse_verb():
# parse_verb1 = parse_verb([('noun', 'apple'), ('verb', 'eat'), ('direction', 'good')])
# assert_equal(parse_verb1,)
def test_parse_subject():
last_sentence = Sentence(('', ''), ('', ''), ('', ''))
#下面的方法返回 Sentence(subj, verb, obj)
last_sentence = parse_subject([('verb', 'eat'), ('direction', 'nice'), ('noun', 'apple')])
assert_equal(last_sentence, ('noun', 'player'))
二 输出结果
E:\Python\exercise\ex49\skeleton>nosetests
....
----------------------------------------------------------------------
Ran 4 tests in 0.015s
OK
E:\Python\exercise\ex49\skeleton\ex49>python
Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from ex49 import *
>>> x = parse_sentence([('verb', 'run'), ('direction', 'north')])
>>> x.subject
'player'
>>> x.verb
'run'
>>> x.object
'north'
>>> x = parse_sentence([('noun', 'bear'), ('verb', 'eat'), ('stop', 'the'), ('noun', 'honey')])
>>> x.subject
'bear'
>>> x.verb
'eat'
>>> x.object
'honey'