2017-06-30 21 views
3

我正在編寫一個程序來修改源代碼文件。我需要解析文件(例如使用megaparsec),修改其抽象語法樹AST(例如使用Uniplate),並儘可能少地改變文件(例如保留空格,註釋...)來重新生成文件。如何編寫不消耗空間的解析器?

因此,AST應包含空間,例如:

data Identifier = Identifier String String 

其中第一字符串是標識符的名稱,並且第二個是空間後。這同樣適用於該語言中的任何符號。

如何爲標識符編寫解析器?

+1

我覺得這已經問過,但不知道一個標準的解決方案(我曾經以一種有點麻煩的方式自己做了這件事)。 – leftaroundabout

回答

2

我最後寫parseLexeme,在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 

更換爲語義識別解析器變爲:

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