Parsec --- 2.5 Sequences and separators (3)

sepBy1を使うことで「英語の文」を単語のリストに分解するパーサをsentenceを作ります.

word:: Parser String
word = many1 (letter <|> digit)


sentence:: Parser [String]
sentence = do words <- sepBy1 word separator
              oneOf ".?!"
              return words

separator:: Parser ()
separator = skipMany1 (space <|> oneOf ",:;'\"")

wordはアルファベットだけでなく数字も許容し,単語間の区切りはカンマ以外のものも,引用符やコロン,セミコロンも許容させています.

ただ,これでは英語の文はパースしきれません.I said "Hello! I'm Taro."みたいな文だと,最後の " がパースされないで残ってしまいます.
そこで,もうちょっと工夫してみます.

word:: Parser String
word = many1 (letter <|> digit)

sentence:: Parser [String]
sentence = do many separator
              words <- sepBy1 word separator
              oneOf ".?!" >> many (oneOf "'\"")
       eof   
              return words

separator:: Parser ()
separator = skipMany1 (space <|> oneOf ",:;?!'\"")

単語区切りに,?!を追加して,さらに引用で文が終わるケースも含め,さらに全部の処理が終わってるかをチェックするようにしています.ついでに冒頭に区切りがあっても無視するようにしました.
けど,まだだめで,「引用文中に複数の文があるケース」は対処できてません.バックトラックが必要なのかもしれませんが,そもそも自然言語を相手にしてるのできりがないので,この辺であきらめます。。。

*Main>  parseTest sentence "\"Hello, I am Hippo 2007!,\" he said suddenly."
["Hello","I","am","Hippo","2007","he","said","suddenly"]