나는 우리가 다듬을 수 있는 이것을 생각해 냈습니다 .
perl -0777 -pe '
BEGIN{
$bs=qr{(?:\\|\?\?/)};
$lc=qr{(?:$bs\n|$bs\r\n?)}
}
s{
/$lc*\*.*?\*$lc*/
| /$lc*/(?:$lc|[^\r\n])*
| (
"(?:$bs$lc*.|.)*?"
| '\''$lc*(?:$bs$lc*(?:\?\?.|.))?(?:\?\?.|.)*?'\''
| \?\?'\''
| .[^'\''"/?]*
)
}{$1 eq "" ? " " : "$1"}exsg'
몇 가지 더 코너 케이스를 처리합니다.
당신이 경우주의 제거 코멘트를, 당신은 코드의 의미를 변화시킬 수는 ( 1-/* comment */-1
같은 구문 분석 1 - -1
하는 동안 1--1
(당신은 코멘트를 제거한 경우 당신이 얻을 거라고하는)이 당신에게 오류를 줄 것이다). 주석을 완전히 제거하는 대신 주석을 공백 문자 (여기에서하는 것처럼)로 바꾸는 것이 좋습니다.
위의 몇 가지 경우를 포함하려고하는이 유효한 ANSI C 코드에서 올바르게 작동해야합니다.
#include <stdio.h>
int main ()
{
printf ( "% d % s % c % c % c % c % c % s % s % d \ n",
1-/ * 주석 * /-1,
/ \
* 의견 * /
"/ * 주석이 아님 * /",
/ * 여러 줄
의견 * /
' "'/ * comment * /, '"',
'\' ',' " '/ * 주석 * /,
'\
\
" ', / * 코멘트 * /
"\\
"/ * 주석이 아님 * /",
"?? /"/ * 코멘트가 아님 * / ",
'??' '+' " '/ *"주석 "* /);
리턴 0;
}
이 출력을 제공합니다 :
#include <stdio.h>
int main ()
{
printf ( "% d % s % c % c % c % c % c % s % s % d \ n",
1 ~ 1,
"/ * 주석이 아님 * /",
' "', '"',
'\' ',' " ',
'\
\
" ',
"\\
"/ * 주석이 아님 * /",
"?? /"/ * 코멘트가 아님 * / ",
'??' '+' " ');
리턴 0;
}
컴파일 및 실행시 모두 동일한 출력을 인쇄합니다.
gcc -ansi -E
프리 프로세서가 수행하는 작업을보기 위해 출력과 비교할 수 있습니다 . 그 코드는하지만, 또한 유효 C99 또는 C11 코드 gcc
trigraph를 기본적으로 지원하지 않습니다 그렇게하지 않습니다와 일 gcc
이 같은 표준을 지정하지 않은 경우 gcc -std=c99
나 gcc -std=c11
또는 추가 -trigraphs
) 옵션을 선택합니다.
이 C99 / C11 (비 ANSI / C90) 코드에서도 작동합니다.
// 댓글
/ \
/ 댓글
// 여러 줄 \
논평
"// 코멘트가 아님"
( gcc -E
/ gcc -std=c99 -E
/ 와 비교 gcc -std=c11 -E
)
ANSI C는 // form
이 의견을 지지하지 않았습니다 . //
그렇지 않으면 ANSI C에서는 유효하지 않으므로 표시되지 않습니다. 하나 인위적인 사건은 어디에서 //
(언급 한 바와 같이 진정으로 ANSI C에 나타날 수 있다 , 당신은 토론 흥미의 나머지 부분을 찾을 수 있음) 할 때입니다 캐릭터 라인 화 연산자를 사용 중입니다.
유효한 ANSI C 코드입니다.
#define s(x) #x
s(//not a comment)
그리고 2004 년에 토론 할 당시에 gcc -ansi -E
실제로 그것을 확장했습니다 "//not a comment"
. 그러나 오늘날 gcc-5.4
에는 오류가 발생하므로 이러한 종류의 구문을 사용하여 많은 C 코드를 찾을 수있을 것입니다.
GNU sed
와 동등한 것은 다음과 같습니다.
lc='([\\%]\n|[\\%]\r\n?)'
sed -zE "
s/_/_u/g;s/!/_b/g;s/</_l/g;s/>/_r/g;s/:/_c/g;s/;/_s/g;s/@/_a/g;s/%/_p/g;
s@\?\?/@%@g;s@/$lc*\*@:&@g;s@\*$lc*/@;&@g
s:/$lc*/:@&:g;s/\?\?'/!/g
s#:/$lc*\*[^;]*;\*$lc*/|@/$lc*/$lc*|(\"([\\\\%]$lc*.|[^\\\\%\"])*\"|'$lc*([\\\\%]$lc*.)?[^\\\\%']*'|[^'\"@;:]+)#<\5>#g
s/<>/ /g;s/!/??'/g;s@%@??/@g;s/[<>@:;]//g
s/_p/%/g;s/_a/@/g;s/_s/;/g;s/_c/:/g;s/_r/>/g;s/_l/</g;s/_b/!/g;s/_u/_/g"
당신의 GNU이 경우 sed
너무 오래 지원 -E
또는 -z
당신이 첫 번째 라인을 교체 할 수 있습니다 :
sed -r ":1;\$!{N;b1}