Haskell AST不完整的位置信息

时间:2016-07-15 22:39:55

标签: parsing haskell abstract-syntax-tree

我一直在尝试构建Haskell AST,以便我可以找出源文件的哪些行存在哪些AST节点。到目前为止,我使用的是Language.Haskell.ParserLanguage.Haskell.Syntax,它们看起来效果相当不错。我可以生成一个树,然后遍历它的每一部分,使用srcLine loc(其中loc是SrcLoc)获取行号。

但是,当解析的文件如下所示时,我遇到了问题:

文件1

1| rangeLeq :: Integer -> NonnegRange
2| rangeLeq n =
3|   Range BoundaryBelowAll (BoundaryAbove n)

该文件可以很容易地写成:

文件2

1| rangeLeq :: Integer -> NonnegRange
2| rangeLeq n = Range BoundaryBelowAll (BoundaryAbove n)

问题是解析器认为这两个是等价的。它不会将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)视为一行。如果不清楚,HsMatch代表代码中的rangeLeq n = Range BoundaryBelowAll (BoundaryAbove n)。由于SrcLoc附带的AST的唯一部分是HsMatch本身,因此解析器假设HsMatch的所有部分都在同一行。

tl;dr如何获得正确的解析,以便源文件中不必要地拆分的行仍然会被标记为相应的行? Id est,我想要一个用<{1}}标记每个节点的解析,而不仅仅是某些节点。

1 个答案:

答案 0 :(得分:0)

haskell-src-extsSrcSpanInfo上有一个位置标记(默认为every subexpression);它应该有足够的细节来消除你的两个例子的歧义。