Haskell程序删除注释

时间:2011-10-26 15:14:55

标签: java parsing haskell io comments

我正在尝试编写一个带有Java程序(.java)的Haskell程序,并在删除所有注释后输出它。输入不必在语法上正确。我已将IO组件设置为如下所示:

main =
  do
     javaFile <- getFileName
     text <- readFile javaFile
     displayProgram ( AAAA )
     return ()

AAAA是获取文本并生成带注释的新文本的表达式 除去。请注意,这些功能是必需的:

getFileName :: IO [Char]
displayProgram :: [String] -> IO ()

我知道算法非常简单:

  1. 搜索//并删除整行文字。
  2. 搜索/*并删除以下所有文字,直至到达*/并删除*/。这当然应该处理块注释和文档注释。
  3. 输出剩余的文字。
  4. 然而,Haskell并不是我最强的语言之一。任何帮助将不胜感激。

5 个答案:

答案 0 :(得分:3)

您的算法错误:您的搜索模式可能出现在字符串中,您的代码需要考虑到这一点。最简单的例子是带有注释的quine:

package quine;
public class Quine {
   /**
    * This is a quine.
    */
   public static void main(String[] args) {
     String s1 = "package quine;\npublic class Quine {\n  /**\n   * This is a quine.\n   */\npublic static void main(String[] args) {\nString s1 = \"";
     // further code elided.
   }
}

答案 1 :(得分:2)

您可以使用以下功能:

stripComments :: String -> String
stripComments [] = []
stripComments ('/':'/':xs) = inComment xs 
stripComments ('/':'*':xs) = inMultiComment xs
stripComments (x:xs) = x : stripComments xs

这将简单地以递归方式“循环”字符串(但是,它是尾递归的,因此它就像一个循环)并复制每个不在注释中的字符。

以下函数用于检测注释的结尾。它们忽略除结束分隔符之外的任何字符,因此模式匹配中的下划线。

inComment :: String -> String
inComment ('\n':xs) = stripComments xs
inComment (_:xs) = stripComments xs
inComment [] = []

inMultiComment :: String -> String
inMultiComment ('*':'/':xs) = stripComments xs
inMultiComment (_:xs) = inMultiComment xs
inMultiComment [] = []

如果您使用更复杂的解析,我建议您在Parsec monadic解析库中进行一次拍摄。

编辑:正如user268396所指出的,你应该知道看起来像Comment的东西可能隐藏在String中。您可能希望使用“inString”函数扩展上述函数,该函数忽略它遇到的字符,但如果遇到这些函数的起始分隔符,则不会切换到inComment或inMultiComment。

答案 2 :(得分:0)

作为类似内容的示例,请参阅我如何从Dot code删除评论等;请注意我正在使用我已经定义(但未完全注释)here的组合器,以便与PolyParse中的Text解析器一起使用。

它不考虑字符串等中的注释,但确实使用/* ... */// ...

删除表单的所有注释

答案 3 :(得分:0)

3种实施方法是可能的:

  • 字符串上的手动模式匹配
  • 使用Text.Parsec包
  • 使用Text.Regex包

对于家庭作业,我会选择手动匹配 为了实现强大的实现,我将使用Text.Parsec 对于快速而肮脏的解决方案,我会使用Text.Regex

答案 4 :(得分:0)

stripComments :: String -> String
stripComments [] = []
stripComments ('/':'/':xs) = inComment xs 
stripComments ('/':'*':xs) = inMultiComment xs
stripComments ('\"':xs) = '\"' : inString xs
stripComments (x:xs) = x : stripComments xs

inComment :: String -> String
inComment [] = []
inComment ('\n':xs) = stripComments xs
inComment (_:xs) = inComment xs

inMultiComment :: String -> String
inMultiComment [] = []
inMultiComment ('*':'/':xs) = stripComments xs
inMultiComment (_:xs) = inMultiComment xs

inString :: String -> String
inString [] = []
inString ('\"':xs) = '\"' : stripComments xs
inString (x:xs) = x : inString xs