Date: Thu, 21 Nov 1996 16:46:20 EDT
Reply-To: whitloi1@WESTATPO.WESTAT.COM
Sender: "SAS(r) Discussion" <SAS-L@UGA.CC.UGA.EDU>
From: Ian Whitlock <whitloi1@WESTATPO.WESTAT.COM>
Subject: Re: removing /*...*/ comments using SAS
Subject: removing /*...*/ comments using SAS
Summary: Code is offered and several subtle points mentioned.
Ian Whitlock <whitloi1@westat.com>
Stephen A'Beckett, Stephen<SABecket@VCRPMRKT.TELSTRA.COM.AU> asked
>do you have any code to remove comments, say, from an 80char SAS variable
>for each "line" of input read in...
>where comments are denoted by /* comment */
>
>i.e.
>
>
>KJNLKJN /**/ FSD/ * /*DDSA */ */ /*
>/* SFSDF */*/ JHB
>KJN
>KJN
>
>
>should end up as...
>
>
>KJNLKJN FSD/ * */
>*/ JHB
>KJN
>KJN
>
>This is "medium-to-complex" in degree of difficulty and someone is
>sure to have done it before.
Here is some code to check. I have only tested with the cards data
given below, so some subtle points may not have been covered
adequately. The code is considerably more complex than that offered by
Melvin Klassen <KLASSEN@UVVM.UVIC.CA> because it handles comments on
multiple lines and the comment markers /* and */ are allowed in quoted
expressions. Note the need to replace comments with a space since
comments are a separator in SAS.
The basic plan is to recognize four possible states - You may be in a
quote where comments are text, or in a comment which is to be dropped,
or looking for one of these states. Text is looped through identifying
the current state and taking the appropriate action to transfer a piece
of TEXT to NEWTEXT. The loop ends when there is no more nonblank text
in TEXT.
data _null_ ;
length newtext $ 80 ;
retain state 0 ; /* 0=free, 1=need single quote,
2=need double quote, 3=need end comment */
input text $char80. ;
put ' text= ' text ;
if text = ' ' then outflg = 1 ;
do while (text ^= ' ') ;
select (state) ;
when (0) link free ;
when (1) link quote1 ;
when (2) link quote2 ;
when (3) link incmnt ;
otherwise error ;
end ;
end ;
if newtext ^= ' ' or outflg then put 'newtext= ' newtext ;
return ;
free:
x1 = index ( text , "'" ) ;
x2 = index ( text , '"' ) ;
x3 = index ( text , "/*" ) ;
select ;
when ( sum ( of x1 - x3 ) = 0 )
do ;
newtext = left(trim(newtext) || text) ;
text = ' ' ;
end ;
when ( x1 > 0 & (x1<x2 | x2=0) & (x1<x3 | x3=0) )
do ;
newtext = left(trim(newtext) || substr (text, 1, x1)) ;
text = substr ( text , x1 + 1 ) ;
state = 1 ;
end ;
when ( x2 > 0 & (x2<x1 | x1=0) & (x2<x3 | x3=0) )
do ;
newtext = left(trim(newtext) || substr (text, 1, x2)) ;
text = substr ( text , x2 + 1 ) ;
state = 2 ;
end ;
when ( x3 > 0 & (x3<x1 | x1=0) & (x3<x2 | x2=0) )
do ;
if x3 > 1 then
newtext = left(trim(newtext) || substr (text, 1, x3-1)) ;
text = substr ( text , x3 + 2 ) ;
state = 3 ;
end ;
otherwise
do ;
put x1= x2= x3= state= ;
stop ;
end ;
end ;
return ;
quote1:
x1 = index ( text , "'" ) ;
if x1 > 0 then
do ;
newtext = left(trim(newtext) || substr (text, 1, x1)) ;
text = substr ( text , x1 + 1 ) ;
state = 0 ;
end ;
else
do ;
newtext = left(trim(newtext) || text) ;
text = ' ' ;
end ;
return ;
quote2:
x2 = index ( text , '"' ) ;
if x2 > 0 then
do ;
newtext = left(trim(newtext) || substr (text, 1, x2)) ;
text = substr ( text , x2 + 1 ) ;
state = 0 ;
end ;
else
do ;
newtext = left(trim(newtext) || text) ;
text = ' ' ;
end ;
return ;
incmnt:
x3 = index ( text , '*/' ) ;
if x3 > 0 then
do ;
* comment is a separator eg. set a/* separator */b ;
* requires a separator to replace a comment ;
text = ' ' || substr ( text , x3 + 2 ) ;
state = 0 ;
end ;
else text = ' ' ;
return ;
cards4 ;
data _null_ /* simple comment test */ ; /* second comment */
/* comment first */ x = 1 ;
y = 2 ;
set a/* subtle point */b ;
put /* harder comment test
on multiple lines
*/
;
put ' test comment in quote /* should be here */' ;
put " test comment in quote /* should be here */" ;
/* entirely a comment */
/*3456789012345678901234567890123456789012345678901234567890123456789012345678*/
run ;
;;;;
Note that the comment
/* comments end with a '*/' */
is not handled by the program. It turns out that SAS will not allow
such a comment to compile without error.
Ian Whitlock