私はどのASTノードがソースファイルのどの行に存在するかを知るために、Haskell ASTを構築しようとしています。これまでのところ、私はLanguage.Haskell.Parser
とLanguage.Haskell.Syntax
を使っていますが、これはかなりうまくいくようです。ツリーを生成してから、各部分を実行して、srcLine loc
(loc
はSrcLoc)を使用して行番号を取得します。Haskell AST不完全な位置情報
解析されたファイルは次のようになりますしかし、私は問題に実行しています:1
1| rangeLeq :: Integer -> NonnegRange
2| rangeLeq n =
3| Range BoundaryBelowAll (BoundaryAbove n)
FILEファイルは簡単にこのように書かれている可能性:
FILE 2
1| rangeLeq :: Integer -> NonnegRange
2| rangeLeq n = Range BoundaryBelowAll (BoundaryAbove n)
問題は、パーサーがこれらの2つを同等に見なすことです。 SrcLocはすべてASTの特定の部分にのみ割り当てられます。だから私はで終わるものを両方のファイル1とファイル2のための次の出力は、次のとおりです。
line 1: HsTypeSig
|--HsIdent (rangeLeq)
|--HsQualType
|--HsContext
|--HsTyFun
|--HsTyCon
|--HsUnQual
|--HsIdent (Integer)
|--HsTyCon
|--HsUnQual
|--HsIdent (NonnegRange)
line 2: HsMatch
|--HsIdent (rangeLeq)
|--HsPVar
|--HsIdent (n)
|--HsUnGuardedRhs
|--HsApp
|--HsApp
|--HsCon
|--HsUnQual
|--HsIdent (Range)
|--HsCon
|--HsUnQual
|--HsIdent (BoundaryBelowAll)
|--HsParen
|--HsApp
|--HsCon
|--HsUnQual
|--HsIdent (BoundaryAbove)
|--HsVar
|--HsUnQual
|--HsIdent (n)
ので、ここでの問題は、それが関数定義を見ているように、ノードのほとんどには位置情報が存在しないということである(HsMatch
)を1行として出力します。それが不明な場合は、HsMatch
はコード内にrangeLeq n = Range BoundaryBelowAll (BoundaryAbove n)
を表します。 SrcLoc
が付属するASTの唯一の部分はHsMatch
であるため、パーサーはHsMatch
のすべての部分が同じ行にあると仮定しています。
tl;dr
ソースファイル内の不必要に分割された行に、適切な行がタグ付けされるように、正しい解析を行うにはどうすればよいですか? Id est、私はすべての単一ノードにというタグを付けるパースを、特定のノードだけでなくSrcLoc
としたい。
Language.Haskell。*モジュールがうまく動作しない場合は、おそらくこのプロジェクトの背後にあるライブラリを試してみてください:http://haskelltools.org彼らのコードはHackageとgithubの両方で利用できるようです。 – ErikR
表現コンストラクタの[大多数](https://hackage.haskell.org/package/haskell-src-1.0.2.0/docs/Language-Haskell-Syntax.html#t:HsExp)はできません単純に 'SrcLoc'を含んでいません。私はこのパーサーがユーザーに完全な正確な行番号を与えることを目指しているとは思っていません。 – user2407038
私は、コンストラクタにはSrcLoc情報が含まれていないことを認識しています。私が探しているのは、異なるパーサーか、行番号を決定する別の方法です。 – nullromo