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、 over を実行する必要がありますIO。Parsec は、この目的のためにParsecT;と呼ばれるモナド変換子を公開します。のタイプをに変更すると、notaInclude動作ParsecT String () IO [SourceItem]するはずです。

ただし、一般的には@soupi の提案を支持し、純粋な解析を続け、解析$include後に s を解決します。しかし、特定のアプリケーションでこのようにする正当な理由があるかもしれません。

于 2016-03-24T08:38:35.497 に答える