4

私がやろうとしていることはかなり単純に思えますが、私はパーセクのHaskell初心者なので、解決策は私にはわかりません。

私には2つのパーサーがあります。たとえば、中間項を解析し、終了項を解析できる場所foo1を考えてみましょう。用語は記号で区切られます。foo2foo1foo2"."

解析する必要のある文は

  • foo2
  • foo1.foo2
  • foo1.foo1.foo2

等々。

私の当初の考えは

do k <- sepBy foo1 (char'.')
   j <- foo2

しかし、それは唯一のケースを捕らえることはできませんfoo2

4

4 に答える 4

4

あなたがしたいendBy、ではありませんsepBy

foo = do k <- foo1 `endBy` char '.'
         j <- foo2
         ... 

これにより、 が出現するたびに区切り文字が強制的に表示されますfoo1

もちろん、endByは で簡単に置き換えるmanyことができ、より明確になる可能性があります。

foo = do k <- many $ foo1 <* char '.' 
         j <- foo2
         ...

または、なしControl.Applicative:

foo = do k <- many $ do x <- foo1; char '.'; return x
         j <- foo2
         ...
于 2010-03-04T03:44:56.043 に答える
2

endByまず、代わりに次のものが必要ですsepBy

do k <- endBy foo1 (char'.')
   j <- foo2

第二に、それは

just foo2 ケースをキャッチ

ドキュメントから:

endBy p sepで区切られた の0 回以上の出現を解析します。によって返される値のリストを返します。psepp

于 2010-03-03T22:13:35.613 に答える
0

次のようなものを試してください

many (foo1 >>= (\v -> char '.' >> return v)) >>= \v1 ->
  foo2 >>= \v2 ->
  -- ...
  -- combine v1 & v2 somehow

(もちろん、スケッチだけです。)

一般に、manyコンビネータはパーセクのクリーネ閉包に相当します。また、既存のパーサーに末尾のドットのような単純なものを追加する場合は、>>/を使用すると、表記>>=を使用するよりも実際にはクリーンで単純になる可能性があります。do

于 2010-03-03T19:27:15.683 に答える
0

確かに、それは foo2 ケースをキャッチします。foo1 に使用すると、ライデンの言葉:

let a = sepBy word (char '.')
parseTest a "foo.bar.baz"
parseTest a "foo"
parseTest a ".baz"
于 2010-03-03T19:42:21.293 に答える