LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous messageNext messagePrevious in topicNext in topicPrevious by same authorNext by same authorPrevious page (November 1996, week 3)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
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
Comments: To: "A'Beckett, Stephen" <SABecket@VCRPMRKT.TELSTRA.COM.AU>

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


Back to: Top of message | Previous page | Main SAS-L page