मैं एक बार इस के साथ आया था जिसे हम निखार सकते हैं:
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 कोड पर ठीक से काम करना चाहिए जो कुछ कोने के मामलों को शामिल करने की कोशिश करता है:
# किंकर्तव्यविमूढ़ <stdio.h>
मुख्य प्रवेश बिंदु()
{
प्रिंटफ ("% d% s% c% c% c% c% c% s% s% d \ n",
1 - / * टिप्पणी * / - 1,
/ \
* टिप्पणी */
"/ * टिप्पणी नहीं * /",
/ * बहु
टिप्पणी */
'"' /* टिप्पणी */ , '"',
'\'','"'/* टिप्पणी */,
'\
\
"', /* टिप्पणी */
"\\
"/ * टिप्पणी नहीं * /",
"?? /" / * टिप्पणी नहीं * / ":
'' '' + '' '' '' * '' टिप्पणी '' /);
वापसी 0;
}
जो यह आउटपुट देता है:
# किंकर्तव्यविमूढ़ <stdio.h>
मुख्य प्रवेश बिंदु()
{
प्रिंटफ ("% d% s% c% c% c% c% c% s% s% d \ n",
1 1,
"/ * टिप्पणी नहीं * /",
'' '', '' '',
'' '', '' ''
'\
\
" ',
"\\
"/ * टिप्पणी नहीं * /",
"?? /" / * टिप्पणी नहीं * / ":
'' '' + '' '');
वापसी 0;
}
संकलित और चलाने पर दोनों एक ही आउटपुट को प्रिंट करते हैं।
आप आउटपुट के साथ तुलना करके gcc -ansi -E
देख सकते हैं कि प्री-प्रोसेसर उस पर क्या करेगा। यह कोड C99 या C11 कोड भी मान्य है, हालाँकि gcc
यह डिफ़ॉल्ट रूप से ट्रिग्राफ समर्थन को निष्क्रिय कर देता है , इसलिए यह 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 कोड है:
#define s(x) #x
s(//not a comment)
और 2004 में चर्चा के समय, gcc -ansi -E
वास्तव में इसका विस्तार किया "//not a comment"
। हालाँकि आज, इस gcc-5.4
पर एक त्रुटि देता है, इसलिए मुझे संदेह है कि हम इस तरह के निर्माण का उपयोग करके बहुत सी कोड पाएंगे।
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}