0

我正在解析一种语言,我想$include在解析时对其他文件有语法。

我的代码:

import Text.ParserCombinators.Parsec
import Text.Parsec.Prim (parserZero)
import Text.ParserCombinators.Parsec.Char
import Control.Monad.Trans
import Data.Functor.Identity

notaInclude :: Parser [SourcesItem]
notaInclude = do
    try $ string "$Include" >> blanks1
    char '"'
    fileName <- quotedStringParser
    char '"'
    i <- getInput
    included <- liftIO $ readFile fileName
    setInput included
    si <- sources
    setInput i
    return si

来自 GHC 的错误消息:

Lazi/Lazi'nh/Language/Sources/Parser.hs:65:17:
    No instance for (MonadIO Identity) arising from a use of `liftIO'
    Possible fix: add an instance declaration for (MonadIO Identity)
    In the expression: liftIO
    In a stmt of a 'do' block: included <- liftIO $ readFile fileName
    In the expression:
      do { try
             (do { string "$Include";
                   blanks1 });
           char '"';
           fileName <- quotedStringParser;
           char '"';
           .... }

我怎样才能让它工作?

4

2 回答 2

1

IMO 解析阶段不是导入文件的正确位置。我建议您将文件作为一个整体进行解析,并在完成后处理结果。

于 2016-03-24T07:52:58.730 回答
0

如果要$include在解析时处理指令,则需要运行IO. Parsec 为此目的公开了一个称为ParsecT; 如果您将类型更改notaIncludeParsecT String () IO [SourceItem]它应该可以工作。

但是,总的来说,我会支持@soupi 的建议,并在解析$include后继续解析和解析。但也许您有充分的理由为您的特定应用程序这样做。

于 2016-03-24T08:38:35.497 回答