2017-06-30 12 views
3

私はソースコードファイルを変更するプログラムを書いています。ファイルを解析し(megaparsecなど)、Abstract Syntax Tree ASTをUniplateなどで変更し、できるだけ変更を加えずにファイルを再生成する必要があります(スペースやコメントなどを保存するなど)。スペースを消費しないパーサの書き方は?

ので、ASTは例えば、スペースが含まれている必要があります

data Identifier = Identifier String String 

最初の文字列は、識別子の名前であり、第二は、それの後にスペースです。同じことが言語の任意のシンボルに適用されます。

Identifierのパーサーを作成するにはどうすればよいですか?

+1

私は、これは前に頼まれていると思いますが、標準の知りません解決策(私はかつてこれをやや厄介なやり方でやっていた)。 – leftaroundabout

答えて

2

私はthis tutorial

data Lexeme a = Lexeme a String -- String contains the spaces after the lexeme 

whites :: Parser String 
whites = many spaceChar 

parseLexeme :: Parser a -> Parser (Lexeme a) 
parseLexeme p = do 
    value <- p 
    w <- whites 
    return $ Lexeme value w 

instance PPrint a => PPrint (Lexeme a) where 
    pprint (Lexeme value w) = (pprint value) ++ w 

に識別子のためのパーサを語彙素を置き換えるために、parseLexemeを書いてしまったが、次のようになります。

data Identifier = Identifier (Lexeme String) 

parseIdentifier :: Parser Identifier 
parseIdentifier = do 
    v <- parseLexeme $ (:) <$> letterChar <*> many (alphaNumChar <|> char '_') 
    return $ Identifier v 

instance PPrint Identifier where 
    pprint (Identifier l) = pprint l 
+0

オペレータの優先順位を扱うため、makeExprParserは使用できませんが、残念です。 – user474491

関連する問題