私はC/C++/javaソースファイルを読み込み、ファイル全体に対して一連の変換を実行しようとしています。最初のフェーズは文字列を削除し、2番目のフェーズはコメントを削除します。Haskell:Parsec:ファイル全体のトランスフォーマーのパイプライン
各フェーズで文字列をいずれかの文字列に変換すると、(どちらの意味でも)それらを一緒にバインドして、変換のパイプラインを作りたいと思います。ファイル全体これはかなり一般的な要件のようです。
import Text.ParserCombinators.Parsec
commentless, stringless :: Parser String
stringless = fmap concat ((many (noneOf "\"")) `sepBy` quotedString)
quotedString = (char '"') >> (many quotedChar) >> (char '"')
quotedChar = try (string "\\\"" >> return '"') <|> (noneOf "\"")
commentless = fmap concat $ notComment `sepBy` comment
notComment = manyTill anyChar (lookAhead (comment <|> eof))
comment = (string "//" >> manyTill anyChar newline >> spaces >> return())
<|> (string "/*" >> manyTill anyChar (string "*/") >> spaces >> return())
main =
do c <- getContents
case parse commentless "(stdin)" c of -- THIS WORKS
-- case parse stringless "(stdin)" c of -- THIS WORKS TOO
-- case parse (stringless `THISISWHATIWANT` commentless) "(stdin)" c of
Left e -> do putStrLn "Error parsing input:"
print e
Right r -> print r
どうすればいいですか?私はparserBindを試したが、うまくいかなかった。
(なぜ誰かが気にしているのであれば、文法を解析したり、C++かJavaかどうかを知ることさえ避けています。すべてのクラスと関数の開始と終了の行番号ですので、#define/ifdefs、テンプレートのプリアンブルと括弧の内容(for節のセミコロンのため)を削除するだけの前処理フェーズを想定しています。どのようなものであれ、タイプと名前を取得するために、もう1つのフェーズでこれらのスニペットを詰め込んだ後、2番目のレベルに再帰してJavaメンバ関数を取得します。
これは機能しますが、少し厄介です。それをラップする演算子を書くことが可能なので、パース(文字列のない>>> commentless) "stdin"入力として書くことができますか? –
do表記を使用できます。 – Lazersmoke