Strip block comments: Difference between revisions
m
→{{header|Wren}}: Changed to Wren S/H
m (→{{header|Phix}}: syntax coloured) |
m (→{{header|Wren}}: Changed to Wren S/H) |
||
(3 intermediate revisions by 3 users not shown) | |||
Line 44:
=={{header|11l}}==
<
V r = ‘’
V i = 0
Line 76:
}’
print(strip_comments(text))</
{{out}}
Line 94:
=={{header|Ada}}==
strip.adb:
<
with Ada.Strings.Unbounded;
with Ada.Text_IO;
Line 186:
end loop;
Ada.Text_IO.Close (File => File);
end Strip;</
output:
<pre>
Line 207:
=={{header|ALGOL W}}==
Handles non-nested block comments, the start and end delimiters are specified as parameters. Comments inside string-literals are retained. The string quote and escape characters are specified as parameters.
<
% strips block comments from a source %
% the source is read from standard input and the result written to %
Line 325:
% text stripBlockComments for C-style source %
stripBlockComments( "/*", "*/", """", "'", "\" )
end.</
{{out}}
<pre>
Line 347:
=={{header|AutoHotkey}}==
<
(
/**
Line 373:
closeC:=RegExReplace(closeC,"(\*|\^|\?|\\|\+|\.|\!|\{|\}|\[|\]|\$|\|)","\$0")
;Display final result
MsgBox % sCode := RegExReplace(code,"s)(" . openC . ").*?(" . closeC . ")")</
<pre>
Line 385:
}</pre>
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f STRIP_BLOCK_COMMENTS.AWK filename
# source: https://www.gnu.org/software/gawk/manual/gawk.html#Plain-Getline
Line 407:
exit(0)
}
</syntaxhighlight>
{{out}}
<pre>
Line 424:
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<
outfile$ = "C:\stripped.c"
Line 461:
CLOSE #infile%
CLOSE #outfile%
ENDPROC</
Output file:
<pre>
Line 476:
=={{header|C}}==
<
#include <string.h>
#include <stdlib.h>
Line 528:
free(s);
return 0;
}</
;Usage:
Specify an input file via the first command line argument, and optionally specify comment opening and closing delimiters with the next two args, or defaults of /* and */ are assumed.
Line 546:
=={{header|C sharp|C#}}==
<
class Program
Line 563:
return sampleText;
}
}</
=={{header|C++}}==
<
#include <iostream>
#include <iterator>
Line 589:
return 1 ;
}
}</
Output:
<pre>
Line 605:
=={{header|Clojure}}==
<
(let [args (conj {:delim ["/*" "*/"]} (apply hash-map args)) ; This is the standard way of doing keyword/optional arguments in Clojure
[opener closer] (:delim args)]
Line 616:
(= (apply str hdtxt) closer) (recur out resttxt (dec delim-count))
(= delim-count 0)(recur (str out (first txt)) (rest txt) delim-count)
true (recur out (rest txt) delim-count))))))</
<pre>user> (comment-strip "This /* is */ some /* /* /* */ funny */ */ text")
hdtxt= Th resttxt=is /* is */ some /* /* /* */ funny */ */ text out= txt=This /* is */ some /* /* /* */ funny */ */ text delim-count=0
Line 661:
=={{header|D}}==
<
string[2] separateComments(in string txt,
Line 749:
showResults(ex2, separateComments(ex2, `#|;`, `[\n\r]|$`));
}</
{{out}}
<pre>===Original text:
Line 808:
{{libheader| System.SysUtils}}
{{Trans|C#}}
<syntaxhighlight lang="delphi">
program Strip_block_comments;
Line 840:
writeln(BlockCommentStrip('/*', '*/', test));
readln;
end.</
{{out}}
<pre>
Line 851:
function something() {
}</pre>
=={{header|EasyLang}}==
<syntaxhighlight lang="easylang">
subr process
i = 1
while i <= len s$
if inc = 0 and substr s$ i 2 = "/*"
inc = 1
i += 1
elif inc = 1 and substr s$ i 2 = "*/"
inc = 0
i += 1
elif inc = 0
write substr s$ i 1
.
i += 1
.
if inc = 0
print ""
.
.
repeat
s$ = input
until error = 1
process
.
input_data
/**
* Some comments
* longer comments here that we can parse.
*
* Rahoo
*/
function subroutine() {
a = /* inline comment */ b + c ;
}
/*/ <-- tricky comments */
/**
* Another comment.
*/
function something() {
}
</syntaxhighlight>
=={{header|F_Sharp|F#}}==
Using .NET's regex counter feature to match nested comments.
If comments here are nested, they have to be correctly balanced.
<
open System.Text.RegularExpressions
Line 897 ⟶ 942:
let balancedC = balancedComments "/*" "*/"
printfn "%s" (balancedC.Replace(sample, ""))
0</
Output
<pre>
Line 913 ⟶ 958:
=={{header|Factor}}==
===Regexp implementation===
<
: strip-block-comments ( string -- string )
R/ /\*.*?\*\// "" re-replace ;
</syntaxhighlight>
===Manual implementation===
<
USING: kernel io accessors strings math sequences locals
io.streams.string multiline prettyprint ;
Line 1,003 ⟶ 1,048:
MAIN: test-strip-block-comments
</syntaxhighlight>
=={{header|Fortran}}==
Line 1,018 ⟶ 1,063:
A feature of Fortran's character comparison is that trailing spaces are ignored, so that "x " and "x " and "x" are all deemed equal. Unfortunate choices of starting and ending delimiter texts can be made if they contain characters in common.
<syntaxhighlight lang="fortran">
SUBROUTINE UNBLOCK(THIS,THAT) !Removes block comments bounded by THIS and THAT.
Copies from file INF to file OUT, record by record, except skipping null output records.
Line 1,102 ⟶ 1,147:
END !All open files are closed on exit..
</syntaxhighlight>
Output: the report is "16 read, 8 written." And in the output file appears...
Line 1,140 ⟶ 1,185:
=={{header|FreeBASIC}}==
{{trans|Liberty BASIC}}
<
Function stripBlocks(text As String, first As String, last As String) As String
Line 1,178 ⟶ 1,223:
Print stripBlocks(source, "/*", "*/")
Sleep</
{{out}}
<pre>
Line 1,186 ⟶ 1,231:
=={{header|Go}}==
For the extra credit: No optional parameters in Go, but documented below is an efficient technique for letting the caller specify the delimiters.
<
import (
Line 1,239 ⟶ 1,284:
function something() {
}`))
}</
=={{header|Groovy}}==
<
/**
* Some comments
Line 1,261 ⟶ 1,306:
"""
println ((code =~ "(?:/\\*(?:[^*]|(?:\\*+[^*/]))*\\*+/)|(?://.*)").replaceAll(''))</
=={{header|Haskell}}==
THE FOLLOWING SOLUTION IS WRONG, as it does not take string literals into account. For example:
<
Comment delimiters can be changed by calling stripComments with different start and end parameters.
<
stripComments :: String -> String -> String -> String
Line 1,282 ⟶ 1,327:
| otherwise = inComment $ tail xs
main = interact (stripComments "/*" "*/")</
Output:
<pre>
Line 1,298 ⟶ 1,343:
=={{header|Icon}} and {{header|Unicon}}==
If one is willing to concede that the program file will fit in memory, then the following code works:
<
every (unstripped := "") ||:= !&input || "\n" # Load file as one string
write(stripBlockComment(unstripped,"/*","*/"))
Line 1,313 ⟶ 1,358:
return result || tab(0)
}
end</
Otherwise, the following handles an arbitrary length input:
<
every writes(stripBlockComment(!&input,"/*","*/"))
end
Line 1,328 ⟶ 1,373:
else fail
}
end</
=={{header|J}}==
<
1 0 0
0 2 0
2 3 2
0 2 2
)</
Example data:
<
/**
* Some comments
Line 1,355 ⟶ 1,400:
function something() {
}
)</
Example use:
<
function subroutine() {
Line 1,366 ⟶ 1,411:
function something() {
}</
Here is a version which allows the delimiters to be passed as an optional left argument as a pair of strings:
<
('/*';'*/') stripp y
:
Line 1,374 ⟶ 1,419:
marks=. (+./(-i._1+#open,close)|."0 1 open E. y) - close E.&.|. y
y #~ -. (+._1&|.) (1 <. 0 >. +)/\.&.|. marks
)</
=={{header|Java}}==
<
public class StripBlockComments{
Line 1,426 ⟶ 1,471:
}
}
}</
=={{header|jq}}==
Line 1,432 ⟶ 1,477:
The filter <tt>strip_block_comments/2</tt> as defined here does not attempt to recognize comments-within-comments.
<
def deregex:
reduce ("\\\\", "\\*", "\\^", "\\?", "\\+", "\\.",
Line 1,440 ⟶ 1,485:
gsub( (open|deregex) + ".*?" + (close|deregex); ""; "m") ;
strip_block_comments("/*"; "*/")</
'''Invocation''':
$ jq -s -R -r -f Strip_block_comments.jq sample_text_for_stripping.txt
Line 1,447 ⟶ 1,492:
{{works with|Julia|0.6}}
{{trans|Python}}
<
"Strips first nest of block comments"
Line 1,521 ⟶ 1,566:
end
main()</
{{out}}
Line 1,545 ⟶ 1,590:
=={{header|Kotlin}}==
<
val sample = """
Line 1,595 ⟶ 1,640:
println(stripBlockComments(sample))
println(stripBlockComments(sample2, "``{", "``}"))
}</
{{out}}
Line 1,623 ⟶ 1,668:
=={{header|Ksh}}==
<
#!/bin/ksh
Line 1,670 ⟶ 1,715:
echo "${testcase}"
</syntaxhighlight>
{{out}}<pre>
Line 1,684 ⟶ 1,729:
=={{header|Liberty BASIC}}==
<
CRLF$ =chr$( 13) +chr$( 10)
Line 1,728 ⟶ 1,773:
end if
next i
end function</
<pre>
Line 1,751 ⟶ 1,796:
=={{header|Lua}}==
It is assumed, that the code is in the file "Text1.txt".
<
fp = io.open( filename, "r" )
Line 1,758 ⟶ 1,803:
stripped = string.gsub( str, "/%*.-%*/", "" )
print( stripped )</
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<
->
Line 1,771 ⟶ 1,816:
function something() {
}</
=={{header|MATLAB}} / {{header|Octave}}==
<
while(1)
ix1 = strfind(str, startmarker);
Line 1,786 ⟶ 1,831:
end;
end;
end;</
Output:
<pre>
Line 1,825 ⟶ 1,870:
=={{header|Nim}}==
{{trans|Python}}
<
proc commentStripper(txt: string; delim: tuple[l, r: string] = ("/*", "*/")): string =
Line 1,871 ⟶ 1,916:
*/
function something() {
}""")</
{{out}}
Line 1,892 ⟶ 1,937:
=={{header|Perl}}==
<
use strict ;
use warnings ;
Line 1,904 ⟶ 1,949:
close FH ;
$code =~ s,/\*.*?\*/,,sg ;
print $code . "\n" ;</
Output:
<pre>
Line 1,919 ⟶ 1,964:
=={{header|Phix}}==
Note that Phix itself supports nested block comments, which this simple approach will not handle properly - see ptok.e/SkipBlockComment() and/or pwa/src/p2js_tok.e/block_comment(), which both use a slightly more convoluted and recursive but also more precise character-by-character method.
<!--<
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">test</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
Line 1,952 ⟶ 1,997:
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">strip_comments</span><span style="color: #0000FF;">(</span><span style="color: #000000;">test</span><span style="color: #0000FF;">))</span>
<!--</
{{out}}
<pre>
Line 1,967 ⟶ 2,012:
=={{header|PHP}}==
<syntaxhighlight lang="php">
function strip_block_comments( $test_string ) {
$pattern = "/^.*?(\K\/\*.*?\*\/)|^.*?(\K\/\*.*?^.*\*\/)$/mXus";
Line 1,991 ⟶ 2,036:
}
" ) . "'";
</syntaxhighlight>
{{out}}
Line 2,009 ⟶ 2,054:
=={{header|PicoLisp}}==
<
(while (echo "/*")
(out "/dev/null" (echo "*/")) ) )</
Output:
<pre>
Line 2,025 ⟶ 2,070:
=={{header|PL/I}}==
<
strip: procedure options (main); /* 8/1/2011 */
declare text character (80) varying;
Line 2,058 ⟶ 2,103:
end;
end strip;</
=={{header|Prolog}}==
Line 2,064 ⟶ 2,109:
Prolog enables grammar rules via the DCG that are ideally suited for this task .
<
:- system:set_prolog_flag(double_quotes,codes) .
Line 2,094 ⟶ 2,139:
zero_or_more(_) --> ! .
</syntaxhighlight>
{{out}}
Line 2,153 ⟶ 2,198:
=={{header|PureBasic}}==
Solution using regular expressions. A procedure to stripBlocks() procedure is defined that will strip comments between any two delimeters.
<
Static specialChars.s = "[\^$.|?*+()"
Protected output.s, nextChar.s, i, countChar = Len(text)
Line 2,203 ⟶ 2,248:
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf</
Sample output:
<pre>--- source ---
Line 2,247 ⟶ 2,292:
=={{header|Python}}==
The code has comment delimeters as an argument and will also strip ''nested'' block comments.
<
'Strips first nest of block comments'
Line 2,270 ⟶ 2,315:
while deliml in txt:
txt = _commentstripper(txt, delim)
return txt</
;Tests and sample output
<
print('\nNON-NESTED BLOCK COMMENT EXAMPLE:')
sample = ''' /**
Line 2,312 ⟶ 2,357:
if __name__ == '__main__':
test()</
<pre>
Line 2,334 ⟶ 2,379:
=={{header|Racket}}==
<syntaxhighlight lang="racket">
#lang at-exp racket
Line 2,363 ⟶ 2,408:
}
})
</syntaxhighlight>
(Outputs the expected text...)
Line 2,369 ⟶ 2,414:
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku"
sub sample {
Line 2,388 ⟶ 2,433:
function something() {
}
'}</
Output:
<pre>
Line 2,402 ⟶ 2,447:
=={{header|REXX}}==
<
* Split comments
* This program ignores comment delimiters within literal strings
Line 2,500 ⟶ 2,545:
oc: Return lineout(oic,oc)
op: Return lineout(oip,op)</
Input:
<pre>
Line 2,564 ⟶ 2,609:
=={{header|Ring}}==
<
example = "123/*456*/abc/*def*/789"
Line 2,578 ⟶ 2,623:
end
see example2 + nl
</syntaxhighlight>
=={{header|Ruby}}==
<
while start_idx = str.index(comment_start)
end_idx = str.index(comment_end, start_idx + comment_start.length) + comment_end.length - 1
Line 2,612 ⟶ 2,657:
END_OF_STRING
puts remove_comments example</
outputs
<pre>
Line 2,625 ⟶ 2,670:
=={{header|Scala}}==
<
def strip1(x: String, s: String = "/*", e: String = "*/") =
x.replaceAll("(?s)"+quote(s)+".*?"+quote(e), "")</
<
val a = x indexOf s
val b = x indexOf (e, a + s.length)
if (a == -1 || b == -1) x
else strip2(x.take(a) + x.drop(b + e.length), s, e)
}</
<
case -1 => x
case i => x.indexOf(e, i + s.length) match {
Line 2,640 ⟶ 2,685:
case j => strip2(x.take(i) + x.drop(j + e.length), s, e)
}
}</
=={{header|Seed7}}==
Line 2,646 ⟶ 2,691:
can be used to replace unnested comments.
<
const proc: main is func
Line 2,669 ⟶ 2,714:
begin
writeln(replace2(stri, "/*", "*/", " "));
end func;</
Output:
<pre>
Line 2,685 ⟶ 2,730:
=={{header|Sidef}}==
For extra credit, it allows the caller to redefine the delimiters.
<
var re = Regex.new(beg.escape + '.*?' + end.escape, 's');
code.gsub(re, '');
}
say strip_block_comments(ARGF.slurp);</
=={{header|SNOBOL4}}==
{{works with|SNOBOL4, SPITBOL for Linux}}
<syntaxhighlight lang="snobol4">
* Program: strip_block_comments.sbl
* To run: sbl -r extract_extension.sbl
* Description: Strip block comments.
* Can use different begin and end delimiters.
* Handles comment nesting and unmatched end delimiters.
* Unmatched begin delimiters remove text to end of file.
* Does not handle quoted delimiters.
* Most null lines are removed, which may not be
* what is desired.
* Comment: Tested using the Spitbol for Linux version of SNOBOL4
* Function strip_block_comments will read a file, or the text after
* the END statement below. Parameter bcom is the beginning comment
* string and parameter ecom is the ending comment string.
*
define('strip_block_comments(bcom,ecom)break_chars,c,newc,pre,pc,b')
pat1 = breakx(*break_chars) . pre (*bcom | *gt(b,0) *ecom) . pc
:(strip_block_comments_end)
strip_block_comments
break_chars = substr(bcom,1,1) substr(ecom,1,1)
newc = ""
b = 0
in1
c = input :f(p60)
p10
c ? pat1 = "" :f(p20)
* matches
le(b,0) :s(leb)f(gtb)
leb
b = leq(pc,bcom) b + 1 :f(leb2)
newc = newc pre :(p10)
leb2
b = leq(pc,ecom) b - 1 :f(error)
:(p10)
gtb
b = leq(pc,bcom) b + 1
b = leq(pc,ecom) b - 1
:(p10)
* nomatches
p20
newc = lt(b,1) newc c
ident(newc) :s(in1)
:(p50)
p50
output = newc
newc = "" :(in1)
p60
output = differ(newc) newc
:(return)
strip_block_comments_end
* Set "begin" comment delimiter (bcom) and "end" comment delimiter (ecom) below
bcom = "/*"
ecom = "*/"
* bcom = "{{*"
* ecom = "?/"
* Strip block comments from the text lines after the END statement
strip_block_comments(bcom,ecom)
END
/**
* Some comments
* longer comments here that we can parse.
*
* Rahoo
*/
function subroutine() {
a = /* inline comment */ b + c ;
}
/*/ <-- tricky comments */
/**
* Another comment.
*/
function something() {
}
----------------------------------------------
With nested comments/* Nested /* comment*/s*/*/!
Unmatched"/*" end delimiters simply remove
to end of file
</syntaxhighlight>
{{out}}
<pre>
function subroutine() {
a = b + c ;
}
function something() {
}
----------------------------------------------
With nested comments*/!
Unmatched"
</pre>
=={{header|Swift}}==
<
func stripBlocks(from str: String, open: String = "/*", close: String = "*/") -> String {
Line 2,729 ⟶ 2,881:
"""
print(stripBlocks(from: test))</
{{out}}
Line 2,746 ⟶ 2,898:
=={{header|Tcl}}==
<
# Convert the delimiters to REs by backslashing all non-alnum characters
set openAsRE [regsub -all {\W} $openDelimiter {\\&}]
Line 2,753 ⟶ 2,905:
# Now remove the blocks using a dynamic non-greedy regular expression
regsub -all "$openAsRE.*?$closeAsRE" $string ""
}</
Demonstration code:
<
* Some comments
* longer comments here that we can parse.
Line 2,771 ⟶ 2,923:
function something() {
}
"]</
Output:
<pre>
Line 2,787 ⟶ 2,939:
=={{header|TUSCRIPT}}==
<
$$ MODE DATA
$$ script=*
Line 2,825 ⟶ 2,977:
d=FILE("destfile")
TRACE *d
</syntaxhighlight>
Output:
<pre>
Line 2,839 ⟶ 2,991:
=={{header|VBA}}==
Stripping block comments might look easy ...
<
'multi line comments
'and what if there are string literals with these delimeters?
Line 2,964 ⟶ 3,116:
Debug.Print String$(60, "-")
Debug.Print t
End Sub</
------------------------------------------------------------
/**
Line 2,999 ⟶ 3,151:
=={{header|Wren}}==
{{trans|Go}}
<
if (start == "" || end == "") {
start = "/*"
Line 3,034 ⟶ 3,186:
var stripC = stripper.call("", "")
System.print(stripC.call(source))</
{{out}}
Line 3,050 ⟶ 3,202:
=={{header|XProfan}}==
<
Parameters string inhalt, beg_delim, end_delim
Declare long start, ende, anzahl
Line 3,075 ⟶ 3,227:
Print Text
WaitKey
End</
{{out}}
<pre>
Line 3,091 ⟶ 3,243:
=={{header|zkl}}==
<
while(xy:=text.span(a,b,True)){ x,y:=xy; text=text[0,x] + text[x+y,*] }
text
}</
The span method takes two tokens and matches the shortest or longest balanced match (if True). It assumes there are no escape characters (such as \ or ""). So we just repeatedly strip out the longest balanced comments until there aren't any left (span returns the empty list). If a comment was unbalanced, span would fail but this code doesn't check that and just assumes no more matches.
{{out}}
|