HaskellのParsecのインデントパッケージは、インデントスタイルの言語(HaskellやPythonなど)を解析する方法を提供します。タイプを再定義しますが、Parsecのモジュールによってエクスポートされた通常のタイプParserのトークンパーサー関数をどのように使用しますか?Text.Parsec.TokenParser
バックグラウンド
- Parsecは、それが何を意味するかにかかわらず、パーサーコンビネーターライブラリです。
- IndentParser 0.2.1は、2つのモジュール
Text.ParserCombinators.Parsec.IndentParserとText.ParserCombinators.Parsec.IndentParser.Token - インデント0.3.3は、単一のモジュールを提供する新しいパッケージです
Text.Parsec.Indent
Parsecには多数のモジュールが付属しています。それらのほとんどは、有用なパーサー(たとえば、改行を解析する newlinefrom )またはパーサーコンビネーター(たとえば、パーサーpをn回実行するfrom )をエクスポートします。Text.Parsec.Charcount n pText.Parsec.Combinator
ただし、モジュールText.Parsec.Tokenは、解析対象の言語の機能を使用してユーザーがパラメーター化した関数をエクスポートする必要があるため、たとえば、関数は「{」を解析した後、「}」を解析する前にbraces pパーサーpを実行します。コメントのようなものを無視します。コメントの構文は言語によって異なります。
これを実現する方法は、呼び出すText.Parsec.Token単一の関数makeTokenParserをエクスポートして、特定の言語のパラメーター(コメントの外観など)を指定し、のすべての関数を含むレコードを返し、そのText.Parsec.Token言語に適合させることです。指定。
もちろん、インデントスタイルの言語では、これらをさらに適応させる必要があります(おそらく、ここでわかりません。後で説明します)。したがって、(おそらく廃止された)IndentParserパッケージがモジュールを提供することに注意してください。Text.ParserCombinators.Parsec.IndentParser.Tokenこれは、のドロップイン置換のように見えますText.Parsec.Token。
ある時点で、すべてのParsecパーサーはモナディック関数であるため、エラーメッセージがソースファイルのどの行と列でエラーが発生したかを示すことができるように、状態を魔法のように処理します。
私の問題
いくつかの小さな理由から、インデントパッケージは多かれ少なかれ現在のバージョンのIndentParserであるようText.ParserCombinators.Parsec.IndentParser.Tokenに見えますが、のようなモジュールは提供されておらず、提供されているだけなText.Parsec.Indentので、どうすれば取得できるのでしょうか。からのすべてのトークンパーサーText.Parsec.Token(reserved "something"予約されたキーワード「something」を解析するもの、またはbraces前述したものなど)。
(新しい)Text.Parsec.Indentは、ある種のモナディック状態の魔法によってソースコードの列ビットが何であるかを理解するように見えるので、whiteSpacefromのようにトークンパーサーを変更する必要はありませんText.Parsec.Token。これがおそらくそれが理由です。交換用モジュールは提供していません。しかし、私は型に問題があります。
がないText.Parsec.Indent場合、すべてのパーサーはタイプParser Somethingであり、Somethingは戻りタイプでありParser、Text.Parsec.Stringで次のように定義されたタイプエイリアスです。
type Parser = Parsec String ()
しかし、Text.Parsec.Indentをインポートする代わりにText.Parsec.String、私は自分の定義を使用します
type Parser a = IndentParser String () a
これにより、すべてのパーセクがタイプになります。ここで、IndentParserはText.Parsec.Indentで定義されています。しかし、私が取得しているトークンパーサーは間違ったタイプです。IndentParser String () SomethingmakeTokenParserText.Parsec.Token
これが今ではあまり意味をなさないのなら、それは私が少し迷っているからです。タイプの問題については、ここで少し説明します。
私が得ているエラーは、Parser上記の1つの定義を別の定義に置き換えようとしたが、からのトークンパーサーの1つを使用しようとするとText.Parsec.Token、コンパイルエラーが発生することです。
Couldn't match expected type `Control.Monad.Trans.State.Lazy.State
Text.Parsec.Pos.SourcePos'
with actual type `Data.Functor.Identity.Identity'
Expected type: P.GenTokenParser
String
()
(Control.Monad.Trans.State.Lazy.State Text.Parsec.Pos.SourcePos)
Actual type: P.TokenParser ()
リンク
- パーセク
- IndentParser(古いパッケージ)
- インデント、Text.Parsec.Indentを提供(新しいパッケージ)
- サンプルコードを使用したパーサータイプの説明
- Text.Parsec.Indentを使用する別の例
残念ながら、上記の例はどちらも、Text.Parsec.Tokenのようなトークンパーサーを使用していません。