Фрагмент Python для удаления комментариев C и C ++ - PullRequest
41 голосов
/ 27 октября 2008

Я ищу код Python, который удаляет комментарии C и C ++ из строки. (Предположим, что строка содержит весь исходный файл C).

Я понимаю, что могу подстроку .match () использовать регулярное выражение, но это не решает вложение /* или наличие // внутри /* */.

В идеале я бы предпочел не наивную реализацию, которая правильно обрабатывает неловкие случаи.

Ответы [ 12 ]

0 голосов
/ 07 марта 2011

Я недавно столкнулся с этой проблемой, когда посещал урок, где профессор требовал, чтобы мы убрали javadoc из нашего исходного кода, прежде чем отправлять его ему для проверки кода. Нам приходилось делать это несколько раз, но мы не могли просто удалить Javadoc навсегда, потому что нам также требовалось создавать HTML-файлы Javadoc. Вот небольшой скрипт на python, который я сделал, чтобы добиться цели. Поскольку javadoc начинается с / ** и заканчивается * /, скрипт ищет эти токены, но скрипт может быть изменен в соответствии с вашими потребностями. Он также обрабатывает однострочные комментарии блока и случаи, когда комментарий блока заканчивается, но в той же строке, что и окончание комментария блока, по-прежнему есть код без комментариев. Надеюсь, это поможет!

ПРЕДУПРЕЖДЕНИЕ. Этот сценарий изменяет содержимое переданных файлов и сохраняет их в исходных файлах. Было бы разумно иметь резервную копию где-нибудь еще

#!/usr/bin/python
"""
 A simple script to remove block comments of the form /** */ from files
 Use example: ./strip_comments.py *.java
 Author: holdtotherod
 Created: 3/6/11
"""
import sys
import fileinput

for file in sys.argv[1:]:
    inBlockComment = False
    for line in fileinput.input(file, inplace = 1):
        if "/**" in line:
            inBlockComment = True
        if inBlockComment and "*/" in line:
            inBlockComment = False
            # If the */ isn't last, remove through the */
            if line.find("*/") != len(line) - 3:
                line = line[line.find("*/")+2:]
            else:
                continue
        if inBlockComment:
            continue
        sys.stdout.write(line)
0 голосов
/ 03 июля 2009

Вам на самом деле не нужно дерево разбора, чтобы сделать это идеально, но вам действительно нужен поток токенов, эквивалентный тому, что генерируется внешним интерфейсом компилятора. Такой поток токенов обязательно должен позаботиться обо всех странностях, таких как начало комментария с продолжения строки, начало комментария в строке, нормализация триграфа и т. Д. Если у вас есть поток токенов, удаление комментариев легко. (У меня есть инструмент, который производит именно такие потоки токенов, как, угадайте, внешний интерфейс реального синтаксического анализатора, который создает настоящее дерево синтаксического анализа :).

Тот факт, что токены индивидуально распознаются регулярными выражениями, предполагает, что в принципе вы можете написать регулярное выражение, которое выберет лексемы комментариев. Реальная сложность набора регулярных выражений для токенизатора (по крайней мере, написанного нами) предполагает, что вы не можете сделать это на практике; писать их по отдельности было достаточно сложно. Если вы не хотите делать это идеально, тогда большинство из приведенных выше решений RE просто хороши.

Теперь, почему вы хотели бы, чтобы раздельные комментарии были вне меня, если вы не создаете обфускатор кода. В этом случае вы должны быть совершенно правы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...