haskell-jp / questions #103 at 2023-05-21 15:58:04 +0900

parsecで構文解析器を作っています。対象ソースコードのどこに構文エラーがあるのか表示したいです。
構文解析器はトークナイザからの出力を受け取り、その構文を解析します。
tokenize :: Parsec String () [Token]
syntaxAnalyze :: Parsec [Token] () SyntaxTree

という型になります。
一回トークナイザを挟むとそのトークンがソースコードの何行何列目にあるかの情報がなくなり、tokenPrim関数でSourcePosの計算ができません。これってどうやって解決したらいいでしょうか?TokenにSourcePosを含めるとパース処理の他に位置計算が含まれるのでコードが読みにくくなるのであまりやりたくないなぁと思っています。

どなたかお教えいただけると非常に助かります!
手元で試してないのでうまく行くか分からないですが、単純な方法として、このように SourcePos を取得する処理を抽象化してはいかがでしょうか?

withPosition :: Parsec String () Token -> Parsec String () (SourcePos, Token)
withPosition someToken = (,) <$> getPosition <*> someToken 

なるほど、この方法だと綺麗に書けそうです。ありがとうございます!