Я пытался создать Haskell AST, чтобы узнать, какие 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 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)
в коде. Поскольку единственная часть AST, которая поставляется с SrcLoc
, является самой 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». Я не думаю, что этот парсер нацелен на то, чтобы дать пользователю полностью точные номера строк - даже ghc не делает это совершенно правильным все время. – user2407038
Я понимаю, что конструкторы не содержат информацию SrcLoc. То, что я ищу, - это либо другой парсер, либо альтернативный метод определения номеров строк. – nullromo