Замена однострочных комментариев C ++ комментариями C89 - PullRequest
2 голосов
/ 15 августа 2011

Какой хороший способ заменить однострочные // input number комментарии многострочными /* input number */ комментариями?

У меня нет никаких предпочтений в отношении языка, используемого для выполнения задачи; Я думал о Perl или Sed. Исходный язык будет C (ANSI X3.159-1989).

Простые сценарии, такие как

while(<>) {
  if (m#^(.*?)//#) {
    print $1;
  } else {
    print $_;
  }
}

будут обмануты строками, содержащими // и не в порядке. Аналогично, // внутри многострочного комментария следует оставить в покое.

Редактировать: Код может предполагать, что триграфов нет.


Это противоположно заменить комментарии в стиле C комментариями в стиле C ++ . Это похоже на Замена // комментариев на / * comments * / в PHP (хотя принятый там ответ не может обработать особые случаи, которые я упомянул, и поэтому, возможно, неправильно).

Ответы [ 3 ]

3 голосов
/ 15 августа 2011

Есть лот угловых вариантов для рассмотрения. Stray // s может появляться в строковых литералах, символьных константах (да, действительно) и в комментариях /* ... */ и //. Сращивание строк с конечными символами \ может действительно испортить ситуацию, а \ можно представить как триграф ??/. Я серьезно сомневаюсь, что я думал обо всех них.

Если вам нужна 100% надежная замена, вам придется воспроизвести (или украсть!) Часть препроцессора компилятора C.

Если вам не нужна 100% надежность, вы можете подумать о том, чтобы просто сделать простую замену, затем сравнить входные данные с выходными данными и вручную устранить любые проблемы. (Обычно для кода, скорее всего, его не будет, но вам нужно будет проверить.) Практичность этого подхода частично зависит от того, сколько кода вам нужно перевести.

В большинстве угловых случаев код не компилируется:

printf("Hello // world\n");

->

print("Hello /* world\n"); */

Вы также можете подумать, действительно ли это необходимо. Большинство компиляторов C89 / C90 поддерживают // комментарии, по крайней мере, по желанию.

2 голосов
/ 16 августа 2011

Вы можете использовать вывод лексера boost :: wave, чтобы заменить все комментарии в стиле c ++ на комментарии в стиле C.не беспокоясь о крайних случаях.

 #include <iostream>
 #include <fstream>

 #include <boost/wave/cpplexer/cpp_lex_token.hpp>
 #include <boost/wave/cpplexer/cpp_lex_iterator.hpp>

 typedef boost::wave::cpplexer::lex_token<> token_type;
 typedef boost::wave::cpplexer::lex_iterator<token_type> token_iterator;
 typedef token_type::position_type position_type;

 int main()
 {
       const char* infile = "infile.h";
     const char* outfile = "outfile.h";
       std::string instr;
       std::stringstream outstrm;
       std::string cmt_str;
       std::ifstream instream(infile);
       std::ofstream outstream(outfile);

       if(!instream.is_open()) {
               std::cerr << "Could not open file: "<< infile<<"\n";
           }
     if(!outstream.is_open()) {
         std::cerr << "Could not open file: "<< outfile<<"\n";
     }

           instream.unsetf(std::ios::skipws);
           instr = std::string(std::istreambuf_iterator<char>(instream.rdbuf()),
                                        std::istreambuf_iterator<char>());

           position_type pos(infile);
           token_iterator  it = token_iterator(instr.begin(), instr.end(), pos,
            boost::wave::language_support(boost::wave::support_cpp|boost::wave::support_option_long_long));
           token_iterator end = token_iterator();

           boost::wave::token_id id = *it;

      while(it!=end) {
         //here you check the c++ style comments 
         if(id == boost::wave:: T_CPPCOMMENT) {
            std::cout<<"Found CPP COMMENT";
            cmt_str = it->get_value();
            cmt_str[0] = '/';
            cmt_str[1] = '*';
            //since the last token is the new_line token so replace the new line
            cmt_str[cmt_str.size()-1] = '*';
            cmt_str.push_back('/');
            //and then append the newline at the end of the string 
            cmt_str.push_back('\n');
            outstrm<<cmt_str;
         }
         else {
           outstrm<<it->get_value(); 
         }
         ++it;
         id = *it;
     }
     outstream<<outstrm;

     return 0;
}

Для получения дополнительной документации см .: http://www.boost.org/doc/libs/1_47_0/libs/wave/index.html

1 голос
/ 15 августа 2011

Это не покрывает 100% угловых случаев, но охватывает те, которые вы упомянули в своем запросе.

#!/usr/bin/env python

import re
from sys import stdin, stdout

for line in stdin.readlines():
  line = line[:-1] # Trim the newline
  stripped = re.sub(r'[\'"].*[\'"]', '', line) # Ignore strings
  stripped = re.sub(r'/\*.*\*/', '', stripped) # Ignore multi-line comments
  m = re.match(r'.*?//(.*)', stripped) # Only match actual C++-style comments 
  if m:
    offset = len(m.group(1)) + 2
    content = line[:offset*-1] # Get the original line sans comment
    print '%s/* %s */' % (content, m.group(1)) # Combine the two with C-style comments
  else:
    print line
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...