1

In my C program, I should convert every "// comment" with "/* comment */"

I thought of the code below with Python re, but could't come up with any idea of how to

insert */ before at the end of the line.

regexp = re.compile(r'//', re.MULTILINE)
c = regexp.sub('/*',c)

Any idea will be grateful. Thank you.

Stevoisiak
  • 23,794
  • 27
  • 122
  • 225
  • 1
    Even with the fixed solutions, this will cause unwanted effects such as replacing `//` within a string literal. – interjay Jul 11 '13 at 09:10
  • 1
    Besides string literals containing `//`, a simple search and replace via regex would also break: `/* // comment */`, which will be replace with `/* /* comment */ */` (the last `*/` will be wrong). – Bart Kiers Jul 11 '13 at 09:25
  • 1
    @BartKiers: Good point. So we would have to ignore `//` within single- or double-quoted strings (which can't be multiline strings in C, right?) and within `/*...*/` (which can be multiline). Anything else? I must admit it doesn't look hopeful, especially since we probably would need indefinite-length lookbehind assertions which Python doesn't have. – Tim Pietzcker Jul 11 '13 at 09:29
  • 1
    @TimPietzcker, indeed, there's also the possibility that a single line comment can contain a closing multi-line comment: `// ... */ ...`. A better way to do this is to *tokenize/scan* the input to match all of these different occurrences. – Bart Kiers Jul 11 '13 at 10:01

2 Answers2

3

Here's a start for a (IMO) "better" solution. It uses regex to scan through the input and match not only single line comments, but also those tokens that can contain //:

#!/usr/bin/env python

import re
import sys

source = """
/* 
 * not 
// a single line 
// comment 
*/

// include stuff
#include<stdio.h>

main()
{
    // comments with a '*/' !
    printf("Again, no single // line comment"); // comment
}
"""

pattern = re.compile(r"""   (//([^\r\n]*)) # match a single line comment
                          | "[^"]*"        # match a string literal
                          | /\*.*?\*/      # match a multi line comment
                          | .              # fall through: match any char
                      """
                         , re.X | re.S)

print("%s" % source)              

print('=' * 40)

for match in pattern.finditer(source):
    if match.group(1):
        # we found a single line comment
        s = match.group(2).replace('*/', '* /')
        sys.stdout.write("/*" + s + " */")
    else:
        # something other than a single line comment, just print it
        sys.stdout.write(match.group())

which will print:

/* 
 * not 
// a single line 
// comment 
*/

// include stuff
#include<stdio.h>

main()
{
    // comments with a '*/' !
    printf("Again, no single // line comment"); // comment
}

========================================

/* 
 * not 
// a single line 
// comment 
*/

/* include stuff */
#include<stdio.h>

main()
{
    /* comments with a '* /' ! */
    printf("Again, no single // line comment"); /* comment */
}
Bart Kiers
  • 166,582
  • 36
  • 299
  • 288
1

Adapted from a previous post that was looking for single line comments in Java, you can use pyparsing:

data = """
class HelloWorld {

    // method main(): ALWAYS the APPLICATION entry point
    public static void main (String[] args) {
        System.out.println("Hello World!"); // Nested //Print 'Hello World!'
        System.out.println("http://www.example.com"); // Another nested // Print a URL
        System.out.println("\"http://www.example.com"); // A nested escaped quote // Print another URL
    }
}"""

from pyparsing import *

dbls = QuotedString('"', '\\', '"')
sgls = QuotedString("'", '\\', "'")
strings = dbls | sgls
g = dblSlashComment.ignore(strings)
g.setParseAction(lambda L,: '/*' + L[0].lstrip('//') + '*/')
print g.transformString(data)

Outputs:

class HelloWorld {

    /* method main(): ALWAYS the APPLICATION entry point*/
    public static void main (String[] args) {
        System.out.println("Hello World!"); /* Nested //Print 'Hello World!'*/
        System.out.println("http://www.example.com"); /* Another nested // Print a URL*/
        System.out.println(""http://www.example.com"); /* A nested escaped quote // Print another URL*/
    }
}
Community
  • 1
  • 1
Jon Clements
  • 138,671
  • 33
  • 247
  • 280