如何编写一个不占用空间的解析器?

时间:2017-06-30 08:07:37

标签: haskell megaparsec

我正在编写程序来修改源代码文件。我需要解析文件(例如使用megaparsec),修改其抽象语法树AST(例如使用Uniplate),并使用尽可能少的更改重新生成文件(例如保留空格,注释等)。

因此,AST应包含空格,例如:

p.stdin.write('0\n')

其中第一个字符串是标识符的名称,第二个字符串是后面的空格。这同样适用于该语言中的任何符号。

如何为Identifier编写解析器?

1 个答案:

答案 0 :(得分:2)

我最后编写了parseLexeme,以替换this tutorial

中的lexeme
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