2011-08-15 54 views
2

用多行/* input number */註釋替換單行// input number註釋的好方法是什麼?用C89替換C++單行註釋

我對用於完成任務的語言沒有任何偏好;我在想Perl或sed。源語言將是C(ANSI X3.159-1989)。

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

簡單的腳本將被包含//串上當,並不確定。同樣,//裏面的多行註釋應該單獨留下。

編輯:代碼可以假設沒有三撇子。


這與replace C style comments by C++ style comments相反。它類似於Replacing // comments with /* comments */ in PHP(雖然接受的答案不能處理我提到的特殊情況,所以可以說是錯誤的)。

+0

需要檢查//是不是在代碼中的任何字符串。 –

回答

2

您可以使用boost :: wave lexer的輸出將所有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

這不會涵蓋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 
3

有一角案件很多考慮。 Stray // s可以出現在字符串文字,字符常量(是的,真的)以及/* ... */評論//評論。與尾部\字符行拼接可以真的搞砸了 - 一個\可以表示爲trigraph ??/。我嚴重懷疑我已經想到了所有這些。

如果您需要100%可靠的替換,您將不得不復制(或竊取!)C編譯器預處理器的一部分。

如果您不需要100%的可靠性,您可以考慮只做一個天真的替換,然後將輸入與輸出進行比較,並手動清除任何問題。 (對於典型的代碼,很可能不會有任何代碼,但您需要檢查。)這種方法的實用性部分取決於您需要翻譯多少代碼。

大多數的角落都將導致代碼不會編譯:

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

- >

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

您也可能會考慮這是否是真的有必要。至少可選地,大多數C89/C90編譯器確實支持//評論。

+0

目的是讓一段代碼與項目的風格指南相匹配。編譯器確實支持單行註釋。至於代碼量,比如6-10 kLOC。 – Charles

+1

@Charles:好的,這是一個很好的理由。它看起來像你需要的是一次性轉換。與創建100%準確的工具相比,您可能會花更少的時間手動修復角落案例。 –