我正在尝试编写一个带有Java程序(.java)的Haskell程序,并在删除所有注释后输出它。输入不必在语法上正确。我已将IO组件设置为如下所示:
main =
do
javaFile <- getFileName
text <- readFile javaFile
displayProgram ( AAAA )
return ()
AAAA
是获取文本并生成带注释的新文本的表达式
除去。请注意,这些功能是必需的:
getFileName :: IO [Char]
displayProgram :: [String] -> IO ()
我知道算法非常简单:
//
并删除整行文字。 /*
并删除以下所有文字,直至到达*/
并删除*/
。这当然应该处理块注释和文档注释。 然而,Haskell并不是我最强的语言之一。任何帮助将不胜感激。
答案 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
答案 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