HaskellのParsecのインデントパッケージは、インデントスタイルの言語(HaskellやPythonなど)を解析する方法を提供します。タイプを再定義しますが、Parsecのモジュールによってエクスポートされた通常のタイプParser
のトークンパーサー関数をどのように使用しますか?Text.Parsec.Token
Parser
バックグラウンド
- Parsecは、それが何を意味するかにかかわらず、パーサーコンビネーターライブラリです。
- IndentParser 0.2.1は、2つのモジュール
Text.ParserCombinators.Parsec.IndentParser
とText.ParserCombinators.Parsec.IndentParser.Token
- インデント0.3.3は、単一のモジュールを提供する新しいパッケージです
Text.Parsec.Indent
Parsecには多数のモジュールが付属しています。それらのほとんどは、有用なパーサー(たとえば、改行を解析する newline
from )またはパーサーコンビネーター(たとえば、パーサーpをn回実行するfrom )をエクスポートします。Text.Parsec.Char
count n p
Text.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
は、ある種のモナディック状態の魔法によってソースコードの列ビットが何であるかを理解するように見えるので、whiteSpace
fromのようにトークンパーサーを変更する必要はありません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 () Something
makeTokenParser
Text.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のようなトークンパーサーを使用していません。