学习使用Parsec库,作业的一部分.
编辑:欢迎使用其他库的建议,重点是解析.
我想要的是用大写字母提取所有单词,从任何句子中提取四个罗盘方向.例如:"比利时完全位于荷兰南部." 应找到并返回"比利时南荷兰".
我无法想象的是如何忽略(吃)任何不是指南针方向的输入.我正在寻找一些类似的东西
'many (not compassDirection >> space)'
Run Code Online (Sandbox Code Playgroud)
但g(h)oogle并没有帮助我.
以下代码显然停留在'many'函数上.
readExpr :: String -> String
readExpr input = case parse (parseLine) "" input of
Left err -> "No match: " ++ show err
Right val -> "Found: " ++ showVal val
parseLine :: Parser GraphValue
parseLine = do
x <- parseCountry
space
many ( some (noneOf " ") >> space )
y <- parseCompass
space
many ( some (noneOf " ") >> space )
z <- parseCountry
return $ Direction [x,y,z]
compassDirection :: Parser String
compassDirection = string "north" <|>
string "south" <|>
string "east" <|>
string "west"
parseCountry :: Parser GraphValue
parseCountry = do
c <- upper
x <- many (lower)
return $ Country (c:x)
parseCompass :: Parser GraphValue
parseCompass = do
x <- compassDirection
return $ Compass x
Run Code Online (Sandbox Code Playgroud)
我不会详细说明,因为这是家庭作业,OP 说“重要的是解析”。
我解决这个问题的方法:
对输入进行标记。将其分解为文字;这将使真正的解析步骤不必担心标记定义(即“%#@[ 是单词的一部分吗?”)或空格。这可以像这样简单,words或者您可以使用 Parsec 进行标记化。然后你就会拥有[Token](或者[String]如果你愿意的话)。
罗盘方向的解析器。您已经有了这个(干得好),但是如果输入[String]不是String.
以大写字母开头的单词的解析器。
一个用于其他所有内容的解析器,只要它看到不是指南针方向或以大写字母开头的单词的标记,就会成功。
可以处理任何标记的解析器,但可以使用代数数据类型来区分好东西和坏东西。
可处理大量标记的解析器
希望这很清楚,但又不太清楚;例如,您仍然需要担心何时丢弃垃圾。基本思想是将问题分解为许多小子问题,解决子问题,然后将这些解决方案粘合在一起。