 .major .clear/window=1 : .title/window=1/start=1,center/bold SCAN Programming Model .text/window=1/start=4,2(                                           >         Input Stream            SCAN             Output Stream(                              Application;           of Text                                   of Text 	 .end_text  .box/start=4,26/end=10,46/bold .line/start=7,8/end=7,24/bold  .label/start=7,25/bold > .line/start=7,46/end=7,66/bold .label/start=7,67/bold > .text/window=1/start=12,2 K VAX SCAN programming is based on the diagram above.  Your application takes M a stream of text as input.  The application searches this stream for patterns H described in the application.  Upon successfully matching a pattern, theM application can replace the text of that pattern.  This replacement text then ; takes the place of the matched text in the output stream.     M Input stream text not matched by the application appears in the output stream 
 unaltered.	 .end_text  .clear/start=20,1 
 .end_frame .text/window=1/start=12,2 J Another way to look at SCAN programming is to draw an analogy to an editor SUBSTITUTE command:   	 .end_text    .text/start=15,2/wide/bold    subs /old-string/new-string/ 	 .end_text  .text/start=16,2  K Each transformation in the SCAN application describes a pattern to look for I in the input stream (old-string) and the text to replace it (new-string). K Each transformation (there can be as many as you like) is applied each time 7 the corresponding pattern is found in the input stream. 	 .end_text  .clear/start=21,1 
 .end_frame   .major .clear/window=1 ? .title/window=1/start=1,center/bold Creating a SCAN Application  .text/window=1/start=5,2/wide        $LSEDIT      filter.scn        $SCAN/DEBUG  filter        $LINK/DEBUG  filter        $RUN         filter 	 .end_text    .text/start=12,2L The mechanics of creating a SCAN application are much the same as creating aK FORTRAN, PASCAL, or BASIC program.  You use an editor to develop the source M program.  The VAX Language-Sensitive Editor is a particularly good choice for L building SCAN programs.  Its built-in knowledge of the SCAN language aids in learning SCAN constructs.   L VAX DEBUG also understands the language SCAN.  The debugger support includesJ special breakpoints for monitoring pattern matching in a SCAN application.	 .end_text  .clear/start=20,1 
 .end_frame   .major .clear/window=1 6 .title/start=1,center/bold Describing a Transformation .text/start=5,2 +                     MACRO name { picture };                            body                       END MACRO;	 .end_text  .text/start=12,2P The ~b macro~ is the vehicle for transforming the input stream.  It has 2 activeS parts, a ~b picture~ and a ~b body~.  The picture describes the pattern to look for H in the input stream.  The body is the algorithm for creating the text to$ replace that matched by the picture.  N How complex can a transformation be?  Macro pictures are capable of describingH patterns as complex as the syntax for a computer language.  A macro bodyI can generate arbitrary text via standard PASCAL-like statements including ; calls on procedures written in the language of your choice. 	 .end_text  .clear/start=21,1 
 .end_frame   .text/start=5,2 <     MACRO name { picture };       MACRO replace_time TRIGGERM                                      { integer ':' integer [ ':' integer ] };         body 8                                       ANSWER 'hh:mm:ss';,     END MACRO;                    END MACRO;    	 .end_text  .text/start=12,2E The simple macro above replaces a time stamp with the generic phrase  L "hh:mm:ss".   The picture describes a time as an integer followed by a colonL followed by another integer.  This second integer can optionally be followedJ by another colon and a final integer.  The ANSWER statement in the body of< the macro does the actual reporting of the replacement text.	 .end_text  .clear/start=17,1 
 .end_frame   .clear/start=4,1 .text/start=4,2          Input    Stream      F   	MACRO replace_time TRIGGER { integer ':' integer [ ':' integer ] }; 		ANSWER 'hh:mm:ss'; 	END MACRO;          Output   Stream    	 .end_text  .box/start=5,12/end=10,65/bold .box/start=16,12/end=21,65/bold   
 .end_frame  > .label/start=6,14 This macro looks for times such as ~b 12:15~B .label/start=7,14 or ~b 1:22:33~ and replaces them with the string> .label/start=8,14 "hh:mm:ss".  Note that partial patterns such8 .label/start=9,14 ~b 33~ or ~b 33:~ are not transformed.  B .label/start=17,14 This macro looks for times such as ~b hh:mm:ss~D .label/start=18,14 or ~b hh:mm:ss~ and replaces them with the string? .label/start=19,14 "hh:mm:ss".  Note that partial patterns such 9 .label/start=20,14 ~b 33~ or ~b 33:~ are not transformed. 
 .end_frame   .major .clear/window=1 - .title/start=1,center/bold Creating a Pattern  .text/start=5,2   F   	MACRO replace_time TRIGGER { integer ':' integer [ ':' integer ] }; 		ANSWER 'hh:mm:ss'; 	END MACRO;   	 .end_text  .text/start=12,2O SCAN uses a ~u two-level approach~ to define the patterns to be searched for in F the input stream.  The first level of patterns describe how to map theO characters of the input stream to units called ~b tokens~.  If your application K was developed to process PASCAL programs, it would describe the elements of I the PASCAL language such as identifiers, integers, strings, comments, and  punctuation marks as tokens.  O The second level of patterns are the ~b macro pictures~.  Pictures are patterns G of tokens.  Thus, integer and ':' used in the above example are tokens. 	 .end_text  .clear/start=21,1 
 .end_frame   .major .clear/window=1 6 .title/start=1,center/bold Creating a Pattern (tokens) .text/start=5,2   0 	TOKEN integer { { '0' | '1' | '2' | '3' | '4' |( 			  '5' | '6' | '7' | '8' | '9' }... };    	TOKEN colon ALIAS ':'  { ':' };    	 .end_text  .text/start=12,2O The example above shows the token declarations for ~u integer~ and ~u':'~.  The Q first declaration defines ~u integer~ to be a digit between 0 and 9, repeated one G or more times.  There are a standard set of operators that aid in token 
 declarations:   /         ~b[ ]~	meaning this pattern is optional /         ~b{ }~	meaning this pattern is required ;         ~b...~	meaning the previous pattern may be repeated E          ~b |~	meaning the previous pattern and the following pattern                   are alternatives	 .end_text 
 .end_frame   .text/start=12,2G The second declaration defines the character colon to be a token.  This R token has the ~b ALIAS~ attribute that states you can refer to the token ~u colon~K by an alternate name, ~u':'~, which is more readable in macro pictures than  the name ~u colon~. 	 .end_text  .clear/start=16,1 
 .end_frame   .text/start=5,2  	SET digit ( '0'..'9' );   	TOKEN integer 		{ digit... };$ 	TOKEN read_key CASELESS { 'READ' };, 	TOKEN space IGNORE 	{ { ' ' | s'ht' }... };    	 .end_text  .text/start=12,2M SCAN provides several aids in declaring tokens, one of which is a ~b set~.  A L set is a subset of the DEC Multinational characters.  This example describesG the set ~u digit~ as the set of digits and then uses it to simplify the $ definition of the token ~u integer~.  K The second token ~u read_key~ describes the keyword READ as the sequence of H four characters R E A D.  The attribute ~b CASELESS~ specifies that any F alphabetic character in the pattern can appear in either uppercase or < lowercase.  Thus, READ, read, or ReAd will match this token.	 .end_text 
 .end_frame   .text/start=12,2J The third token definition ~u space~ describes one or more spaces or tabs.M In addition, this token has another aid, the attribute ~b IGNORE~, specifying J that the token should be ignored during picture-matching.  This is useful,I because it eliminates the need for describing where spaces can occur in a J macro picture.  This attribute says that they can occur zero or more times between any two tokens. 	 .end_text  .clear/start=18,1 
 .end_frame       .major .clear/window=1 8 .title/start=1,center/bold Creating a Pattern (pictures) .text/start=5,2     B 	MACRO read_statement TRIGGER { read id [ { ',' | ';' } id ]... };	 .end_text    .text/start=12,2N The second level of pattern matching involves arranging your token definitionsM in a ~b macro picture~ to describe the pattern you are interested in finding. N A macro picture, like a token pattern, is very similar to a syntax diagram youA might find in many DIGITAL manuals.  Standard operators are used:   /         ~b[ ]~	meaning this pattern is optional /         ~b{ }~	meaning this pattern is required ;         ~b...~	meaning the previous pattern may be repeated E          ~b |~	meaning the previous pattern and the following pattern                   are alternatives	 .end_text 
 .end_frame   .clear/start=4,1 .text/start=12,2H A final consideration in building patterns is factoring common patterns.M Token declarations provide such factoring because all the macro pictures in a K module share a set of tokens.  It is also frequently useful to share common I macro pictures.  A typical example is the description of a data type in a H programming language.  Such a pattern is needed in the description of a % variable, type, and record component. 	 .end_text 
 .end_frame   .clear/start=18,1  .text/start=4,2      MACRO data_type SYNTAX         { INTEGER          | BOOLEAN 2         | [ FIXED ]   STRING '(' integer_value ')'2         | VARYING     STRING '(' integer_value ')'2         | [ DYNAMIC ] STRING '(' integer_value ')'0         | RECORD { component ',' }... END RECORD!         | POINTER TO data_type };      END MACRO;  8     MACRO component SYNTAX { identifier ':' data_type };     END MACRO;       MACRO declare_stmt TRIGGERG         { DECLARE identifier [ ',' identifier ]... ':' data_type ';' };      END MACRO;  B     MACRO type_stmt TRIGGER { TYPE identifier ':' data_type ';' };     END MACRO;	 .end_text 
 .end_frame   .text/start=12,2  P This example shows that each SCAN macro has one of two attributes, ~b SYNTAX~ orR ~b TRIGGER~.  A macro with the TRIGGER attribute is one that works like the editorL SUBSTITUTE command.  It searches the input stream for its pattern.  A macro J with the SYNTAX attribute is an extension of the picture of another macro.P ~u Data_type~ is such a syntax macro, describing the syntax of a data type.  TheZ macros ~u declare_stmt~ and ~u type_stmt~ reference the name of the macro ~u data_type~ atG the point in their picture where they require the pattern that has been  factored into ~u data_type~.  	 .end_text  .clear/start=21,1 
 .end_frame   .clear/start=4,1 .text/start=4,2   B     MACRO type_stmt TRIGGER { TYPE identifier ':' data_type ';' };       END MACRO;	 .end_text  .text/start=12,2S Thus, the pattern for ~u type_stmt~ consists of the keyword ~u TYPE~ followed by an O ~u identifier~ followed by a colon followed by a data type, where the form of a = data type is given by the picture of the macro ~u data_type~. 	 .end_text 
 .end_frame   .major .clear/window=1 4 .title/start=1,center/bold Creating Replacement Text   .text/start=4,2 N The picture of a macro matches a sequence of text in the input stream, and theG body of the macro generates the text to replace the text matched by the 6 picture.  This is the basic principle of a SCAN macro.  K When generating replacement text, there are 3 important points to consider:   2 	1) How to capture the text matched by the picture  ) 	2) How to construct the replacement text   & 	3) How to report the text constructed	 .end_text 
 .end_frame   .major .clear/window=1 ) .title/start=1,center/bold Capturing Text    .text/start=4,2        MACRO find_time TRIGGER ? 	{ hour: integer ':' minute: integer [ ':' second: integer ] }; 	 .end_text    .text/start=12,2P You can capture the text matched by a macro picture using ~b picture variables~.L Picture variables are dynamic string or integer variables that are placed inP the actual picture at the points where you wish to gather information. ~u Hour~,V ~u minute~, and ~u second~ are examples of dynamic string picture variables.  ~u Hour~Z will collect the text matched by the 1st ~u integer~ token; ~u minute~ the 2nd ~u integer~0 token; and ~u second~ the 3rd ~u integer~ token.	 .end_text 
 .end_frame   .box/start=8,22/end=10,55/bold .label/start=9,2 Input Stream " .label/start=9,26 The time is 1:33 .text/start=12,2N Given the above input stream, the 3 picture variables would have the following  values in the body of the macro:             hour          1            minute        33/           second                  (null string)   N Note that ~u second~ contains the null string.  It appears in an optional partJ of the pattern that was not matched.  Thus, it was never assigned a value.	 .end_text  .clear/start=21,1 
 .end_frame   .clear/start=4,1 .text/start=4,2        MACRO find_time TRIGGER : 	{ time:{ integer ':' integer [ ':' second: integer ] } };	 .end_text  .box/start=8,22/end=10,55/bold .label/start=9,2 Input Stream ' .label/start=9,26 The time is 12:59:59.  .text/start=12,2N Picture variables are not limited to appearing before tokens.  They can appearM before syntax macros, in which case they collect the replacement text of that O syntax macro.  They can also appear before a phrase such as ~u time~ above.  In M this example ~u time~ will capture the text matched by the entire picture and > ~u second~ will capture the text of the final optional phrase.  "             time          12:59:59             second        :59 	 .end_text 
 .end_frame   .clear/start=4,1 .text/start=4,2   6 	MACRO integer_list TRIGGER { { value: integer }... };	 .end_text  .text/start=12,2L The final aspect of using picture variables has to do with repetition.  ThisQ picture can match one or more ~u integer~ tokens.  The question arises, what does W the picture variable ~u value~ hold?  ~u Value~, in this situation, is a tree variable. M The concept of trees will be discussed later.  At this point, it is enough to B know that a tree can hold multiple values like an array in PASCAL.	 .end_text 
 .end_frame   .box/start=8,22/end=10,55/bold .label/start=9,2 Input Stream , .label/start=9,26 12 345 67890 444 3333333 1 .text/start=12,2N Given this input stream, the picture variable would hold the following values:            value( 1 )        12           value( 2 )        345           value( 3 )        67890          value( 4 )        444"          value( 5 )        3333333          value( 6 )        1	 .end_text 
 .end_frame     .major .clear/window=1 8 .title/start=1,center/bold Constructing Replacement Text .text/start=4,2 : 	o Variable, constant, and external procedure declarations  ? 	o Executable statements such as assignment, IF-THEN-ELSE, FOR,  	  WHILE, and CASE  % 	o Subroutine and function procedures   B 	o Expressions including powerful operators and built-in functions	 .end_text  .text/start=12,2  N The second part of creating replacement text is the actual construction of theN text.  This is done using an algorithm.  The SCAN language contains a completeE programming language for this purpose.  This part of the language has ? similarities to PASCAL, and contains the features listed above. 	 .end_text 
 .end_frame   .text/start=4,2 ,     CONSTANT h = 'hhhhhhhhhhhhhhhhhhhhhhhh';,     CONSTANT m = 'mmmmmmmmmmmmmmmmmmmmmmmm';,     CONSTANT s = 'ssssssssssssssssssssssss';       MACRO find_time TRIGGER ? 	{ hour: integer ':' minute: integer [ ':' second: integer ] };   @ 	ANSWER h[ 1..LENGTH( hour ) ], ':' ;    ! replace hour with h'sB 	ANSWER m[ 1..LENGTH( minute ) ];        ! replace minute with m's  ) 	IF s <> ''				! replace seconds with s's  	THEN					! if present$ 	    ANSWER s[ 1..LENGTH( second )]; 	END IF;       END MACRO;	 .end_text  .clear/start=20,1 
 .end_frame   .clear/start=4,1 .text/start=4,2 *     TOKEN date_mark CASELESS { '<date>' };  /     MACRO find_date_mark TRIGGER { date_mark }; ) 	DECLARE time_buffer: FIXED STRING( 11 ); - 	CALL sys$asctim( *, time_buffer, *, false );  	ANSWER time_buffer;     END MACRO;	 .end_text  .text/start=12,2N One of the most significant features of the SCAN language is that you can callG procedures written in other VAX/VMS languages.  Thus, you can constructwJ replacement text in procedures written in languages such as VAX BASIC, VAXK PASCAL, or VAX SCAN.  In addition, you can use the VAX/VMS Run-Time Library A routines and VAX/VMS System Services to help solve your problems.a  L This example replaces the symbol <date> in the input stream with the current5 date obtained from the ~u sys$asctim~ system service.4	 .end_textb
 .end_frame   .major .clear/window=1e5 .title/start=1,center/bold Reporting Replacement Texts .text/start=4,2C@ 	ANSWER h[ 1..LENGTH( hour ) ], ':' ;    ! replace hour with h's, 	IF INTEGER( hour ) <= 11		! append am or pm 	THEN  	    ANSWER 'am';r 	ELSE  	    ANSWER 'pm';e 	END IF;	 .end_textu .text/start=12,2E The final part of creating replacement text is reporting that text asiJ replacement text.  SCAN provides a special statement for this purpose, the ~b ANSWER~ statement.e  M Consider the replacement text as a buffer of text.  Before executing the body M of a macro, this buffer is empty.  Each of the ANSWER statements appends text I to the text already in the buffer.  If the body of your macro executes noUK ANSWER statements, then the text matched by the picture will be replaced by/J the null string.  This is a convenient way of removing text from the input stream.t	 .end_texte
 .end_frame   .major .clear/window=1s+ .title/start=1,center/bold VAX SCAN Program  .text/start=4,2aG You have now encountered many of the components of a SCAN program.  Now 2 let's bring them together into a complete program.  6 The major structural components of a SCAN program are:
 	o program	 	o modulet 	o macro 	o procedure  P A ~b program~ is a VAX/VMS executable image (an .EXE file) that you run with DCLV RUN command.  A ~b program~ is composed of one or more ~b modules~.  Another term used( for a ~b program~ is an ~b application~.  O A ~b module~ may be written in any of the VAX/VMS languages including VAX SCAN. P Each ~b module~ is compiled using the appropriate language compiler to create anJ object module (an .OBJ file).  These object modules are combined using the* VAX/VMS Linker to produce the ~b program~.	 .end_textS
 .end_frame   .clear/start=4,1 .text/start=4,2 J A module is central to the SCAN language in several ways.  First, the SCANO compiler compiles a single module at a time.  Second, although your applicationeK can span multiple modules, the picture matching constructs in SCAN (such assL tokens and macros) are local to a module.  When the picture-matching processO is started, it applies the macros defined in a module against the input stream.   N Macros are the vehicle for transforming the input stream to produce the output2 stream.  Each module can have zero or more macros.  K Procedures perform the same function in SCAN as in other languages.  A SCAN M module can define zero or more procedures.  Most modules contain at least onelK procedure, because one is needed to start the picture-matching process.  InrM addition, procedures are used for communicating between SCAN modules when theoN program consists of more than one module.  Procedures are also the cornerstoneM of the VAX/VMS Common Language Environment.  In this environment, a procedure M (some languages call them routines, functions, or subroutines) written in oneA= language can be called by modules written in other languages. 	 .end_text 
 .end_frame   .clear/start=4,1 .text/start=4,2g MODULE change_times;     !+K     !   This is a very simple program that locates all occurrences of times      !   of the form:"     !   		a date  dd-mmm-yyyy   or     !   		a time  hh:mm:ss.xxxxe     !   and replaces them with:      !   		"dd-mmm-yyyy"      !   		"hh:mm:ss.xxxx"gE     !   Presumably, this could be used as a filter program to get ride4     !   of all date and time dependencies in a file.     !-  <     CONSTANT h = 'hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh';<     CONSTANT m = 'mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm';<     CONSTANT s = 'ssssssssssssssssssssssssssssssssssssssss';<     CONSTANT x = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';<     CONSTANT y = 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy';<     CONSTANT d = 'dddddddddddddddddddddddddddddddddddddddd';	 .end_text/
 .end_frame   .text/start=4,22        SET digit 			( '0' .. '9' );!     TOKEN integer 		{ digit... };r!     TOKEN colon ALIAS ':' 	{':'};a     TOKEN dot ALIAS '.' 	{'.'};e:     TOKEN month CASELESS 	{ 'jan' | 'feb' | 'mar' | 'apr' $ 				| 'may' | 'jun' | 'jul' | 'aug' & 				| 'sep' | 'oct' | 'nov' | 'dec' };"     TOKEN dash ALIAS '-' 	{ '-' };       MACRO replace_date TRIGGER m) 	{ dd:integer '-' month '-' yy:integer };d  8 	ANSWER d[ 1..length(dd) ], '-mmm-', y[ 1..length(yy) ];       END MACRO;	 .end_texts .clear/start=20,1t
 .end_frame   .text/start=4,2t       MACRO replace_time TRIGGER 	{ hh:integer ':' mm:integer) 	[ ':' ss:integer [ '.' xx:integer ] ] };x  8 	ANSWER h[ 1..length( hh ) ], ':', m[ 1..length( mm ) ];   	IF ss <> '' 	THEN $ 	    ANSWER ':', s[ 1..length(ss) ]; 	END IF;   	IF xx <> '' 	THEN $ 	    ANSWER ':', x[ 1..length(xx) ]; 	END IF;     END MACRO;	 .end_textr
 .end_frame .clear/start=21,1r .text/start=4,2r        PROCEDURE main_routine MAIN;   	!+h> 	!   Start the picture matching process.  The input stream and8 	!   the output stream are defined via the logical names 	!   TIME.DAT and SYS$OUTPUT.L 	!-u   	START SCANn 	    INPUT FILE 'TIME.DAT' 	    OUTPUT FILE 'SYS$OUTPUT';       END PROCEDURE;   END MODULE;a	 .end_textt .clear/start=20,1s  
 .end_frame   .major .clear/window=1h2 .title/start=1,center/bold Flow of Control in SCAN .text/start=4,2 L A key concept to understanding the CHANGE_TIMES program is understanding the+ order in which the statements are executed./  I You will investigate this using a pseudo VAX Debug session.  A reasonable'J amount of liberty is takenin the information displayed, however, the basic3 steps can be reproduced in an actual debug session.e  I To prepare for the session the program must be compiled, linked, and run.u   	$SCAN/deb change_timesw 	$LINK/deb change_times > 	$TYPE     time.dat	! to show the contents of the input stream8 	The TITANIC struck the iceberg 14-Apr-1912 at 11:55 pm. 	$RUN      change_times 	 .end_textm
 .end_frame   .clear/start=4,1 .text/start=4,2m    ->  PROCEDURE main_routine MAIN;   	!+ > 	!   Start the picture matching process.  The input stream and	 .end_text  .text/start=12,2N The RUN command will start the execution of the program at the main procedure.J If the main procedure is written in SCAN, as it is in this case, it is theK procedure with the MAIN attribute.  At this point you will set a few breaksa) to monitor the progress of the program.      	DBG> set break/event=trigger~
 	DBG> step  O The first command asks the debugger to break whenever a trigger macro starts or  terminates.r	 .end_text.
 .end_frame   .clear/start=4,1 .text/start=4,2N 	!-e  
 ->	START SCAN| 	    INPUT FILE 'TIME.DAT' 	    OUTPUT FILE 'SYS$OUTPUT';  	 .end_texti .text/start=12,2I The statements in the body of the procedure ~u main_routine~ are executednG sequentially, thus the next statement is the START SCAN statement.  TheiH purpose of this statement is to initiate the picture-matching process by specifying:o) 	1) the input stream:			the file TIME.DAT , 	2) the output stream:			the file SYS$OUTPUT= 	3) the set of tokens and macros to use: those in this modulec  	 	DBG>step 	 .end_text 
 .end_frame   .clear/start=4,1 .box/start=6,16/end=8,75/boldd .label/start=7,4 Input Stream.M .label/start=7,18 The TITANIC struck the iceberg ~b 14-Apr-1912~ at 11:55 pm.c .text/start=12,2H Upon executing the START SCAN statement, flow of control in your programE changes dramatically.  The macros start seaching the input stream foriH transformations to be made.  Statements are no longer executed one afterL another like in most languages.  The macros that are executed, and the orderM that they are invoked, is driven by the sequence of data in the input stream.s  O Given the input stream above, the date ~b 14-Apr-1912~ would fire off the macroC ~u replace_date~.p	 .end_textt
 .end_frame   .clear/start=4,1 .text/start=4,2    ->  MACRO replace_date TRIGGER ;) 	{ dd:integer '-' month '-' yy:integer };d  8 	ANSWER d[ 1..length(dd) ], '-mmm-', y[ 1..length(yy) ];  	 .end_texta .text/start=12,2H The input stream successfully matches the picture.  You can monitor this# by setting a couple of tracepoints:r4 	DBG> set trace/event=token	! trace each token built= 	DBG> set trace/event=picture	! trace matching of the pictureg 	DBG> goO Since the macro's picture matched successfully, the next sequence of statements~J to be executed are those in the body of the macro ~u replace_date~.  AfterN reaching the end of the macro's body, and doing the text replacement specified5 by the body, searching of the input stream continues.2	 .end_text 
 .end_frame   .clear/start=4,1 .box/start=6,16/end=8,75/bold. .label/start=7,4 Input StreamcM .label/start=7,18 The TITANIC struck the iceberg dd-mmm-yyyy at ~b 11:55~ pm.  .text/start=12,2P Next, the integer ~b 11~ (start of 11:15) fires off ~u replace_date~.  Note thatY both ~u replace_date~ and ~u replace_time~ start with an integer.  Since ~u replace_date~oL appears first in the program it is tried first.  When a colon is encounteredI rather than a dash, ~u replace_date~ fails and ~u replace_time~ is tried.E  R ~b 11:15~ does match the picture of ~u replace_time~, thus, the body of this macroE is sequentially executed, text replacement takes place, and searching' continues for more patterns.	 .end_textc
 .end_frame   .clear/start=4,1 .text/start=4,2O 	START SCAN  	    INPUT FILE 'TIME.DAT' 	    OUTPUT FILE 'SYS$OUTPUT';   ->  END PROCEDURE;  	 .end_text  .text/start=12,2G This cycle of searching the input stream for patterns and replacing the_M matched text continues until the end of the input stream is reached.  With no:K further transformations to make, the START SCAN statement is finished doing2E its job.  Sequential execution of statements following the START SCAN~K statement continues.  This example has no further statements to execute, sor= the procedure ~u main_routine~ returns control to its caller.s	 .end_textt
 .end_frame   .clear/start=4,1 .text/start=4,2sK From this example it is easy to extrapolate the points where a SCAN programxG can interact with procedures in other modules.  First, a procedure in atJ separate module can call a SCAN procedure that does a START SCAN.  Thus, aJ separate module, perhaps written in VAX FORTRAN, can call a SCAN procedureI passing it a file or string for a set of SCAN macros to analyze.  This isrD the general way other languages take advantage of SCAN capabilities.  L The second point interaction can occur is in a macro body.  A macro body canM call a procedure to do some work.  This procedure could be a VAX/VMS Run-TimeaL Library routine, system service, or a procedure written in another language.	 .end_texta  ? .label/start=19,center/reverse End of Pattern Matching Tutorialx
 .end_frame   .end_scriptc  