Анализ исходного файла Haskell без явного заголовка ‘module M where’ с помощью GHC 7

#parsing #haskell #ghc

#анализ #haskell #ghc

Вопрос:

Ребята из будапештской группы по функциональному программированию meetup наконец убедили меня перенести Tandoori на GHC 7. Все получается нормально, но у меня проблема с разбором .hs исходных файлов без module M where заголовка.

Вот автономная версия кода, которая вызывает внутренний анализатор GHC для анализа исходных файлов:

 module Main where

import SrcLoc
import FastString
import Outputable (showSDoc)
import Parser (parseModule)
import Lexer (unP, mkPState, ParseResult(..))
import StringBuffer (hGetStringBuffer)
import DynFlags (defaultDynFlags)
import System.Environment (getArgs)

parseMod src_filename = do 
  buf <- hGetStringBuffer src_filename
  let loc = mkSrcLoc (mkFastString src_filename) 1 0
      dflags = defaultDynFlags
  case unP Parser.parseModule (mkPState dflags buf loc) of
    POk pst rdr_module -> return rdr_module
    PFailed srcspan message -> error $ showSDoc message

main = do 
  args <- getArgs
  case args of
    [src_filename] -> parseMod src_filename
    _ -> error "Usage: parse-test filename.hs"
  

вот входной файл, который работает:

 foo = 1
  

вот еще один вариант, который работает:

 module M where

foo = 1 
bar = 2
  

и вот тот, который не:

 foo = 1
bar = 2
  

Для этого вывод программы, приведенный выше, является:

 *** Exception: parse error on input `='
  

Обратите внимание, что я использую синтаксический анализатор GHC вместо чего-то подобного haskell-src , потому что реальный код также использует переименователь из GHC.

Комментарии:

1. И… какое сообщение об ошибке, если таковое имеется? AFAIK, GHC требует, чтобы у вас была функция main в модуле без заголовка.

2. Я добавил сообщение об ошибке к вопросу. Требование для main проверяется не синтаксическим анализатором, а где-то гораздо ниже по потоку в конвейере компилятора. Обратите внимание, что вы можете загрузить двухстрочный пример, например, в GHCi.

Ответ №1:

Мы просто добавляем строку заголовка модуля к источнику, который мы хотим получить от анализатора GHC. Помогло бы это вам?

Комментарии:

1. Кто такой «вы» в этом контексте? Доступен ли код для определения необходимости заголовка syntetic module и последующего добавления к нему?

2. «Ты» или, лучше, я — это я сам. 😉 У меня есть приложение, которое знает, что заголовка модуля нет и что оно должно добавить его само. Если вы не знаете, что можно использовать Haskell lexer для разделения заданных источников на токены и поиска по module ключевому слову. Который может отображаться только один раз или не отображаться вообще. Что дает вам ваш ответ.

3. То есть, по сути, вы его записываете, затем просматриваете выходные данные, а затем снова анализируете его? На самом деле я ищу более разумное решение:) Вызов ghc непосредственно из командной строки, похоже, хорошо справляется с компиляцией этих программ, поэтому, несомненно, внутри GHC 7 есть какой-то путь к коду, который я мог бы использовать.

4. Нет, я не понимаю этого, я знаю, что заголовка модуля нет. Я просто предложил это — по общему признанию, уродливое — решение, если вы не знаете, нужно ли добавлять заголовок модуля или нет.