From: fairfield@slacvx.slac.stanford.edu
Subject: Re: Pattern
Organization: Stanford Linear Accelerator Center
Date: Wed, 30 Dec 1992 23:37:21 GMT

In article <1hsqeoINNmqe@usenet.INS.CWRU.Edu>, at913@cleveland.Freenet.Edu (Mirko Vukovic) writes:
> I am converting a fortran code from single to double precision on a VAX.  
> I a TPU routine that searches for constants in the program by using the
> following patterns
>
>         aaaa.bbbbbX
>             .bbbbbX
>         aaaa.X
>
>         aaaa any number of digits
>         bbbb any number of digits
>         X any character except d,D
>
> and puts the cursor on the end of a line where the pattern was found.
>
> I came up with the following patterns:
>
> predig:=span('0123456789');			<--- for aaaa
> posdig:=anchor&span('0123456789');		<--- for bbbb
> per:='.';					<--- for .
> exp:=anchor&(notany('dD')|line_end);		<--- for X
>
> find :=((predig&per&exp)|(per&posdig&exp)|(predig&per&posdig&exp));
>
> However the above does detect numbers like 123.12D00, ie if I have more than
> one digit after the period followed by D.
>				         
> Is that because in posdig anchor forces the span to match only one character?

    No, it's because the first "alternation" in the pattern "find", that is,
"predig&pre&exp" matches the "123.1" in "123.12D00" (the NOTANY('dD') matches
the "1" following the period, see below).  Remember, the order of the alternate 
subpatterns is important.  

    Also, I would modify your pattern variables to use concatenation "+" 
rather than linkage "&" (see Section 2.7.3.2, p.2-15, in the VAXTPU manual).
This will remove the need for ANCHOR and make it clear (to yourself) what
you're searching for.  For example:

        digits := span('0123456789');
        exp    := notany('dD01234567879') + 
			(span('01234567879') + line_end | line_end);
	patt1  := digits + '.' + digits + exp;
	patt2  :=          '.' + digits + exp;
	patt3  := digits + '.' + exp;
	find   := ( patt1 | patt2, | patt3);

A final remark on this pattern: I would think it would be better to use
an ANY('eE') in the "exp" pattern (aren't "E" and "D" the only allowed
exponent characters in VAX Fortran?).  My "extension" to the exp pattern
above won't prevent you from matching any arbitrary other character.
Also, do you really need to match the line_end condition?  If you do, fine,
but you'd better be sure the files you're editing don't have any trailing
tabs or spaces...

> Also, how do I put a cursor on the end of a range?

    SEARCH returns a range, so just POSITION (END_OF (range)).  For example,
in testing it's nice to see exactly what range SEARCH returned.  You could
do something like this:

	r1 := Search_Quietly (find, FORWARD);
	If r1 <> 0 Then
	    Position (End_Of (r1));
	    r2 := Create_Range (Beginning_Of (r1), Mark (NONE), REVERSE);
	    Update (CURRENT_WINDOW);	! <- not necessary, but could be useful
	Endif;

An earlier remark above implies you'd like to leave the cursor at the end of
the line.  In that case, after the Position (r1), or whatever, just do
a Position (LINE_END).

		Cheers, Ken
--
 Dr. Kenneth H. Fairfield    |  Internet: Fairfield@Slac.Stanford.Edu
 SLAC, P.O.Box 4349, MS 98   |  DECnet:   45537::FAIRFIELD (45537=SLACVX)
 Stanford, CA   94309        |  BITNET    Fairfield@Slacvx
 ----------------------------------------------------------------------------
 These opinions are mine, not SLAC's, Stanford's, nor the DOE's...
Newsgroups: vmsnet.tpu