1
parse' :: Parser a -> String -> [(a,String)]
parse' p inp = p `with` inp

parse :: Parser a -> String -> [a]
parse p inp = [ v | (v,[]) <- parse' p inp ]

mkMany1 :: (Parser a -> Parser [a]) -> Parser a -> Parser [a]
mkMany1 many p = do x <- p
                    xs <- many p
                    return (x:xs)

many1L :: Parser a -> Parser [a]
many1L = mkMany1 manyL

manyL :: Parser a -> Parser [a]
manyL p = (many1L p) ||| (success [])

'<'文字、'>'または(スペース)を含まない多くの部分文字列の文字列を解析しようとしています' 'が、パーサーが終了していないようです。誰かが私が見逃しているものについていくつかの指針を教えてもらえますか?

textValid :: Char -> Bool
textValid c =  c /= '<' && c /= '>' && not (isSpace c)      

text :: Parser String 
text = manyL (sat textValid)

次のコマンドを実行しようとすると、決して終了しません。

parse (manyL text) "abc def <"
4

1 に答える 1

6

問題は、manyL parser入力を消費せずに成功できることです (空のリストを返します)。

また、 の引数として入力を消費せずに成功できるパーサーを渡してはなりませんmanyL。その場合、まさにそのような無限ループが発生するためです。

最初に入力のプレフィックスをtext消費した後、スペースで始まるものが残ります。そのため、それを試してみると、の先頭にある文字と同じ数の文字を消費し、つまり 0 - を返します。それは同じ入力を残します。今度は、それが成功するかどうかをもう一度確認します..."abc"" def <"StringtexttextValidString[]manyL texttext

おそらく定義する必要があります

text = many1L (sat textValid)

そのため、text入力を消費しないと成功しません。おそらく、解析が成功するたびに残りの入力の先頭からスペースを消費することをお勧めします。

text = do
    result <- many1L (sat textValid)
    skipSpaces
    return result

skipSpaces実装するために残っています)。

于 2013-04-24T19:23:18.470 に答える