2016-11-20 11 views
3

その中の単語のリストに「これはありますか」という文字列があれば、「これ」、「ある」、「物語」、 "all"、 "about"、 "how"]をReadP Stringのインスタンスとして使用しますか?私はさまざまな方法を試しましたが、そのうちの1つはこれです:コンマで区切られた値の文字列をhaskellの文字列のリストに解析する方法は?

parseStr :: ReadP String 
parseStr = do 
    skipSpaces 
    n <- munch1 isAlphaOrDigit 
    skipComma 
    return $ n 

すべての値を解析して最後の値を解析します。

parseLast :: ReadP String 
parseLast = do 
    skipSpaces 
    n <- munch1 isAlphaOrDigit 
    return $ n 

parseLet = (many parseStr) +++ parseLast 

としてではなく、それはどちらか動作しませんでした:私はこの解析とそれを組み合わせた場合、私は思いました。任意のヒント?

編集:以上の定義

isAlphaOrDigit :: Char -> Bool 
isAlphaOrDigit a = (isDigit a) || (isAlpha a) 
comma = satisfy (','==) 
skipComma = const() <$> some comma 
+1

カッコは、あなたの入力の一部であるかどうかを ""(this、is、a、story、all、about、how) – duplode

+0

また、 'isAlphaOrDigit'と' skipComma'の定義を見る必要があります。 – duplode

+1

カッコは入力の一部であり、定義は次のとおりです。 'isAlphaOrDigit :: Char - > Bool isAlphaOrDigit a =(isDigit a)|| (isAlpha a) '' skipComma = const()<$>いくつかのコンマ ' – jazaniac

答えて

2

パーサa +++ bは、どちらかのパーサが生成されたすべての結果を生成する、baへの入力文字列全体と全体の入力文字列を送信します。代わりに、文字列の最初の部分をaに送信し、2番目の部分をbに送信するパーサーが必要な場合は、結果を組み合わせることができます。代わりにこれを試してみてください:

parseLet = liftA2 (\ss s -> ss ++ [s]) (many parseStr) parseLast 

多くのパーサライブラリもこの正確なユースケースのために(おそらくわずかに異なる名前で)manySepByコンビネータを提供します。あなたはそのようなことのためにReadP図書館を通して見てみることを検討するかもしれません。

+0

答えをありがとう!私はあなたの定義を実装しようとしましたが、空のリストを返すことになりました。次に、sepByを使用して新しいparseLet関数を実装しようとしました: 'parseLet = do' ' skipOpen' 'a sepBy parseStr comma' ' skipClose' 'return $ a'しかしこれも空リストを返しました。 – jazaniac

+0

@jazaniac(1) 'Text.ParserCombinators.ReadP'から' between'を使用して、かっこを処理できます。 (2)推測: 'sepBy'ベースのバージョンを試す前に' parseStr'から 'skipComma'を削除しましたか? – duplode

+0

@duplode今、 'parseLet = open close(sepBy parseStr comma)'のように見えますが、残念ながらemptylistを返しています。 skipCommaは以前は削除されていませんでしたが、削除したばかりで残念ながらemptylistが返されました。 'close = satisf( '(' ==)' 'close = satisf( ')' ==)' – jazaniac

関連する問題