Программа Haskell для удаления комментариев - PullRequest
0 голосов
/ 26 октября 2011

Я пытаюсь написать программу на Haskell, которая берет Java-программу (.java) и выводит ее со всеми удаленными комментариями.Ввод не должен быть синтаксически правильным.Я настроил компонент ввода-вывода так:

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

AAAA - это выражение, которое берет текст и создает новый текст с удаленными комментариями.Обратите внимание, что эти функции необходимы:

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

Я знаю, что алгоритм довольно прост:

  1. Найдите // и удалите всю эту строку текста.
  2. Найдите /* и удаляйте весь следующий текст, пока не достигнете */, а также удалите */.Это, конечно, должно заботиться как о блочных комментариях, так и о документах.
  3. Выведите оставшийся текст.

Тем не менее, Haskell не является одним из моих самых сильных языков.Любая помощь будет принята с благодарностью.

Ответы [ 5 ]

3 голосов
/ 26 октября 2011

Ваш алгоритм неверен: ваши шаблоны поиска могут встречаться внутри строк, и ваш код должен это учитывать.Простейшим примером является 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.
   }
}
2 голосов
/ 26 октября 2011

Вы можете использовать функцию, подобную этой:

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.1010 * РЕДАКТИРОВАТЬ: Как указал user268396, вы должны знать, что что-то похожее на комментарий может скрываться в строке.Возможно, вы захотите расширить вышеупомянутые функции с помощью функции «inString», которая не игнорирует встречаемые символы, но не переключается на inComment или inMultiComment, если встречает начальные разделители для них.

0 голосов
/ 30 мая 2018
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
0 голосов
/ 27 октября 2011

Возможны 3 варианта реализации:

  • ручное сопоставление с образцом в строках
  • с использованием пакета Text.Parsec
  • с использованием пакета Text.Regex

Для домашней работы я бы пошел с ручным соответствием Для надежной реализации я бы пошел с Text.Parsec Для быстрого и грязного решения, я бы пошел с Text.Regex

0 голосов
/ 27 октября 2011

В качестве примера для чего-то подобного, посмотрите, как я удаляю комментарии и т. Д. Из Код точки ; обратите внимание, что я использую комбинаторы, которые я определил (но не полностью прокомментировал) здесь для использования с анализатором текста в PolyParse.

Он не учитывает комментарии в строках и т. Д., Но делает , удаляет все комментарии формы, используя /* ... */ и // ...

...