2010-11-28 9 views
2

アムで文字列を区切るので、これに明白な答えがある場合に謝罪...


私は分割機能を作りたいです文字列すなわち以下のすべてのリスト[文字列]:ハスケル:選択したサブ文字列とハスケルにまだ新しい空白

[["int", "x", "=", "1"], ["y", ":=", "x", "+", "123"]] 

:文字列の同じ文字列すなわち[[文字列]]へ

["int x = 1", "y := x + 123"] 
["int x= 1", "y:= x+123"] 
["int x=1", "y:=x+123"] 


すべて
最初の[String]にmap words.linesを使用できます。あなたがメインの文字列を分割するために、様々なサブ文字列"="":=""+"などを使用しているだろう -

は、しかし、私も考慮に他人を取るために任意の本当にきちんとした方法を知りません。



私はparsecを見て、あなたの文字列を解析するための簡単な文法を構築するだろうHaskellの:-)

答えて

7

プレリュードは、Haskellの式のレクサーであるlexと呼ばれるあまり知られていない便利な機能が付属しています。これらは必要なフォームに一致します。

lex :: String -> [(String,String)] 

どのような奇妙なタイプだけど!このリストは、標準タイプのパーサとのインタフェースのためのものですが、私はかなり確信しています。lexは常に1または0の要素を返します(0は解析の失敗を示します)。タプルは(token-lexed, rest-of-input)です。したがって、lexはトークンを1つだけプルします。だから、文字列全体をレックスする簡単な方法は:

lexStr :: String -> [String] 
lexStr "" = [] 
lexStr s = 
    case lex s of 
     [(tok,rest)] -> tok : lexStr rest 
     []   -> error "Failed lex" 

このコードはひどい形です。 Maybeを使用して妥当なエラーを返す代わりにerrorを明示的に呼び出すと、lexは1または0の要素のみを返します。これを行うコードはほぼ同じ長さですが、かなり抽象的です。

3

に私を啓発するために時間を割いていただきありがとうございます。

+0

ありがとうございます。しかし、私はそれを「純粋に」、つまり他のライブラリなしで簡単に行うことを望んでいました。ああ、できればモナドもなく(どちらかといえば、まだ笑っていないので)。 –

+0

あなたが始めている時、パセックはあまり良くありません。他の誰かが書いたパーサーを編集するのがかなり簡単だと分かったが、自分で書くことはしばらく私の能力を超えていた。モナドでいくつかの快適さが必要です。 – luqui

+0

十分に公正。それはオプションとして考慮する価値がある。あなたがモナドでない何か他のものを望むなら、あなたはカスタムオプションで行かなければならないかもしれません。 –

0

どのように言葉を使用してについて。) words :: String -> [String] と言葉文句を言わない空白の世話..

words "Hello World" 
= words "Hello  World" 
= ["Hello", "World"] 
+0

オハイオ州 - ちょうど私が長い間enougthを考えていないことが分かった:単語は "y:="を "y"、 ":="に分割しないので、あなた自身の単純なパーサー言葉の助け:P)、またはparsecを使う(とにかく知っておくと良い選択です)。 –

+0

プラス「言葉」の使用はすでに質問に記載されていました;) –

+0

Wonderfull - 私は、私のコメントの混乱を利用して、睡眠をとるためのインジケータとして使い始めるべきです。 –