代码之家  ›  专栏  ›  技术社区  ›  Pierre Carbonnelle

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

  •  4
  • Pierre Carbonnelle  · 技术社区  · 7 年前

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

    data Identifier = Identifier String String
    

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

    如何为标识符编写解析器?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Pierre Carbonnelle    7 年前

    我最后写了parseLexeme,来代替中的lexeme 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