90 lines
2.3 KiB
D
90 lines
2.3 KiB
D
import std.algorithm, std.regex;
|
|
|
|
string[2] separateComments(in string txt,
|
|
in string cpat0, in string cpat1) {
|
|
int[2] plen; // to handle /*/
|
|
int i, j; // cursors
|
|
bool inside; // is inside comment?
|
|
|
|
// pre-compute regex here if desired
|
|
//auto r0 = regex(cpat0);
|
|
//auto r1 = regex(cpat1);
|
|
//enum rct = ctRegex!(r"\n|\r");
|
|
|
|
bool advCursor() {
|
|
auto mo = match(txt[i .. $], inside ? cpat1 : cpat0);
|
|
if (mo.empty)
|
|
return false;
|
|
plen[inside] = max(0, plen[inside], mo.front[0].length);
|
|
j = i + mo.pre.length; // got comment head
|
|
if (inside)
|
|
j += mo.front[0].length; // or comment tail
|
|
|
|
// special adjust for \n\r
|
|
if (!match(mo.front[0], r"\n|\r").empty)
|
|
j--;
|
|
return true;
|
|
}
|
|
|
|
string[2] result;
|
|
while (true) {
|
|
if (!advCursor())
|
|
break;
|
|
result[inside] ~= txt[i .. j]; // save slice of result
|
|
|
|
// handle /*/ pattern
|
|
if (inside && (j - i < plen[0] + plen[1])) {
|
|
i = j;
|
|
if (!advCursor())
|
|
break;
|
|
result[inside] ~= txt[i .. j]; // save result again
|
|
}
|
|
|
|
i = j; // advance cursor
|
|
inside = !inside; // toggle search type
|
|
}
|
|
|
|
if (inside)
|
|
throw new Exception("Mismatched Comment");
|
|
result[inside] ~= txt[i .. $]; // save rest(non-comment)
|
|
return result;
|
|
}
|
|
|
|
|
|
void main() {
|
|
import std.stdio;
|
|
|
|
static void showResults(in string e, in string[2] pair) {
|
|
writeln("===Original text:\n", e);
|
|
writeln("\n\n===Text without comments:\n", pair[0]);
|
|
writeln("\n\n===The stripped comments:\n", pair[1]);
|
|
}
|
|
|
|
// First example ------------------------------
|
|
immutable ex1 = ` /**
|
|
* Some comments
|
|
* longer comments here that we can parse.
|
|
*
|
|
* Rahoo
|
|
*/
|
|
function subroutine() {
|
|
a = /* inline comment */ b + c ;
|
|
}
|
|
/*/ <-- tricky comments */
|
|
|
|
/**
|
|
* Another comment.
|
|
*/
|
|
function something() {
|
|
}`;
|
|
|
|
showResults(ex1, separateComments(ex1, `/\*`, `\*/`));
|
|
|
|
// Second example ------------------------------
|
|
writeln("\n");
|
|
immutable ex2 = "apples, pears # and bananas
|
|
apples, pears; and bananas "; // test for line comment
|
|
|
|
showResults(ex2, separateComments(ex2, `#|;`, `[\n\r]|$`));
|
|
}
|