- IBM主机技术一本通
- 吕新民编著
- 3344字
- 2020-08-26 22:17:25
6.13 COPY语句
下面显示的是COPY语句的通用语法。
COPY语句与其他的COBOL语句有很大的不同,因为其他的COBOL语句都是在程序运行时执行的,而COPY语句则是在程序编译的时候执行的。COPY语句是一个库文件服务语句,用来将预先写好的文本复制到程序的源代码中。每条COPY语句必须以句号结束。如果没有在COPY语句中指定库名(LibraryName),则系统假定要访问的库名指定在编译作业流中的SYSLIB所指定的文件名中。
如果指定短语SUPPRESS,表示在程序编译清单中不出现嵌套在复制成员中的内容,COPY语句要求COBOL编译选项LIB是生效的。
预先写好的源程序段可以在程序编译时复制到程序中来,这样很多公司就可以将标准的文件描述、记录描述和过程描述预先写好,存放到复制库中,其他程序员不用在程序中重复编写而是直接使用COPY语句复制到程序中来,既节省了程序员的工作量,也可以保证所有人使用的是同一套标准格式。
编译器在处理包含有COPY语句的源程序时,首先处理所用的COPY语句,然后对COPY以后的源程序做编译处理。处理COPY语句时,编译器将复制库中预先写好的文本代码复制到源程序中,置换原来程序中的从COPY开始到句号(.)结束的语句。如果在COPY语句中没有指定REPLACING短语,复制库中的文本会原封不动地抄到源程序中来。
每条COPY语句必须以句号(.)结束。注解行和空行可以出现在复制库文本中,出现在复制库文本中的注解行和空行都会复制到源程序中,但如果注解行或空行中有正好与REPLACING短语后面的变量(Identifier1)或常量(Literal1或word1)相同时,注解行或空行就不会复制到源程序中。
只有处理完所有的COPY和REPLACING语句后,才能确定COBOL源程序语法的正确性。单凭复制库文本的内容是不能独立确定程序的语法正确性的。
COPY可以出现在源程序的任何地方,作为IBM主机COBOL的扩充,COPY语句可以嵌套调用。但是,被嵌套调用的COPY语句不能包含REPLACING短语,同样,带有REPLACING短语的COPY语句也不可以包含嵌套的COPY语句。
COPY语句不能递归(Recursion),也就是说,在一组嵌套的COPY语句中,一个复制库成员名只能出现一次。比如,假定源程序有语句COPY X,而复制库文件X又含有语句COPY Y,这时,复制库文本文件Y就一定不能出现COPY X或COPY Y语句。
当你想把复制库文件中的部分或全部文本复制到源程序之后做某些修改,就要使用COPY REPLACING短语,所修改的内容只反映在源程序中,而原来的复制库文本文件则保持不变。
REPLACING短语匹配的过程是以文本单词(Text Word)为单位进行的,这里所谓的单词并不等同于英语中的单词,它指的是:
● 用引号(‘’)括起来的一串字符。
● 用下面的分隔符隔开的字符串。
✧ 空格。
✧ 伪文本分隔符(==)。
✧ 逗号(,)。
✧ 左括号或右括号。
当指定REPLACING短语时,复制库文本会复制进源程序,然后所有与Identifier1匹配的文本单词会置换为Identifier2。
为了修改复制库文本文件中的数据名的一部分,程序员可以使用带有标准伪文本(Pseudo Text)分隔符(==)的REPLACING选项。伪文本(Pseudo-Text)是一组用分隔符双等号(==)括起来的字符串,伪文本可以包含最多322个字符。请记住,伪文本字符串必须用分隔符括起来。伪文本使得我们可以一次置换多个单词或字符。伪文本1(PseudoText1)不能为空值(Null),也不能只由空格字符、逗号、分号或注解行组成。伪文本前后的空格不作为文本比较的字符,嵌套在中间的空格表明包含多个文本单词则要参与比较。伪文本不能包含单词COPY。
6.13.1 程序例子(COPY命令)
下面的程序是使用COPY命令的例子,这是完整的源程序,至于COPY库文本我们没有在这里单独列出来,因为在下面的编译清单中,你可以看到它们的全貌。
000001 IDENTIFICATION DIVISION. 000002 * 000003 PROGRAM-ID. COPY2. 000004 AUTHOR. NEWMAN LV. 000005 * 000006 ENVIRONMENT DIVISION. 000007 * 000008 INPUT-OUTPUT SECTION. 000009 * 000010 DATA DIVISION. 000011 * 000012 000013 FILE SECTION. 000014 * 000015 WORKING-STORAGE SECTION. 000016 * COPY DIRECTLY 000017 COPY FILREC1. 000018 * COPY REPLACING 000019 COPY FILREC1 REPLACING 000020 REC1 BY REC2 000021 FILLER BY MAST-NOTES. 000022 * COPY REPLACING TEXT WORDS 000023 COPY FILREC4. 000024 COPY FILREC4 REPLACING 000025 PIC BY MAST 000026 X BY Y 000027 9 BY 0. 000028 * NESTED COPY. 000029 COPY FILREC2. 000030 * COPY REPLACING PSEUDO TEXT1 000031 COPY FILREC3. 000032 COPY FILREC3 REPLACING ==:MAST-:== BY ==MST-==. 000033 * COPY REPLACING PSEUDO TEXT2 000034 COPY FILREC3 REPLACING ==:MAST-:== BY ==WS-==. 000035 * COPY REPLACING PSEUDO TEXT3 000036 COPY FILREC3 REPLACING ==:MAST-:== BY ====. 000037 * COPY SUPPRESS 000038 COPY FILREC1 SUPPRESS. 000039 * 000040 PROCEDURE DIVISION. 000041 * 000042 DISPLAY 'FOR TEST COPY VERB... ' 000043 STOP RUN.
6.13.2 程序编译清单(COPY命令)
下面显示的是上面的程序COPY2的编译清单,由于我们可以看到复制库中的源代码,所以我们会在这里对每个COPY命令做讲解。
第17行的COPY命令,直接将复制库文件FILREC1的内容抄到源程序中,它的内容显示在第18行和第24行,请注意第7列的字符‘C’,表示该行的内容是从别的地方复制过来的,而不是源程序中原来就有的。
第26行到第28行的COPY REPLACING命令除了将FILREC1中的内容复制到程序之外,还要将REC1置换为REC2,FILLER置换为MAST-NOTES。COPY命令执行的结果显示在第29行到第35行,如果你够仔细,你就会发现MAST-REC1并没有按照要求改成MAST-REC2,问题出在哪里?原因其实很简单,是我们对文本单词(Text Word)的理解出了误差,所谓的文本单词要么是用引号括起来的字符串,要么是用几个规定的分隔符分隔开来的字符串,因此,REC1并不是一个完整的文本单词,而MAST-REC1才是一个完整的文本单词。所以,只有将REPLACING后面的REC1 BY REC2写成MAST-REC1 BY MAST-REC2才能达到置换的目的。与REC1相反,第35行的FILLER成功置换成了MAST-NOTES,因为FILLER是一个完整的文本单词。
第37行的COPY命令简单明了,直接将FILREC4的内容抄到程序中,其结果显示在第38行到第44行。接下来的第45行到第48行的COPY REPLACING命令,则是为了更深刻地说明什么叫做文本单词!第46行的PIC BY MAST短语,目的是将所有的文本单词PIC置换成字符串MAST,从第50行到第55行的结果你能看到,左边的PIC原封不动地保留下来,而右边的PIC则全部被置换成MAST了,因为左边的PIC不是文本单词!第47行的短语X BY Y是要将所有的文本单词X置换成Y,再看看第50行到第55行的结果,右边的4个X确实都换成了Y,因为它们都是由空格和左括号隔离开来的文本单词。第48行的短语9 BY 0是要把所有的文本单词9换成0,再看看结果,第50行的9换成了0,但第53行的S9和V99都没有发生变化,因为9自己不是一个文本单词,而S9和V99则是。看了这个例子,你应该对什么是文本单词有了很深刻的印象了吧。
第57行的COPY语句看起来没有什么特别之处,闪光点在库复制文件FILREC2,本身又带有COPY语句,这就形成了嵌套的COPY语句,这是IBM主机上的COBOL对标准COBOL的一个扩充,对于这种嵌套语句的一个限制是,它们都不能有REPLACING短语。嵌套COPY语句的结果显示在第58行到第69行,其中的第65行到第69行的内容来源于另外一个复制库文件CMBWORDS。
接下来的几个例子是介绍如何使用伪文本复制库文件的。第71行的COPY语句直接显示了伪文本复制文件是如何编码的,请注意第72行到第77行的描述,我们在字符串‘MAST-’的前后加上了冒号(:),目的是在使用REPLACING短语时更容易操作。第79行的COPY语句将所有的字符串‘:MAST-:’置换成‘MST’,结果显示在第80行到第86行。
第88行的COPY语句则将‘:MAST-:’置换为‘WS-’,结果显示在第89行到第95行。第97行的COPY REPLACING语句则是直接将字符串‘:MAST:’去掉,结果显示在第98行到第104行。使用伪文本作为记录格式的描述,在实际的程序开发中是经常使用的,因为它可以更灵活地适用于各种情况。
第106行的COPY语句使用了SUPPRESS短语,其效果就是在源程序编译清单中不会出现所调用的复制库文件的内容,这样可以缩短编译清单的长度,使程序员能够更好地将精力集中于程序逻辑本身。在汇编语言中也有类似的功能,其格式为PRINT NOGEN。
下面是COPY2程序的完整编译清单,显然我们对它做了一些编辑,因为现在的程序版本是通过不了编译程序的检查的,但为了说明COPY语句的用法,我们将所有的出错信息都删掉了。
000001 IDENTIFICATION DIVISION. 000002 * 000003 PROGRAM-ID. COPY2. 000004 AUTHOR. NEWMAN LV. 000005 * 000006 ENVIRONMENT DIVISION. 000007 * 000008 INPUT-OUTPUT SECTION. 000009 * 000010 DATA DIVISION. 000011 * 000012 000013 FILE SECTION. 000014 * 000015 WORKING-STORAGE SECTION. 000016 * COPY DIRECTLY 000017 COPY FILREC1. 000018C 01 MAST-REC1. 000019C 05 MAST-ACNO PIC 9(14). 000020C 05 MAST-IDNO PIC X(16). 000021C 05 MAST-NAME PIC X(35). 000022C 05 MAST-BALANCE PIC S9(13)V99 COMP-3. 000023C 05 MAST-REMARKS PIC X(38). 000024C 05 FILLER PIC X(39). 000025 * COPY REPLACING 000026 COPY FILREC1 REPLACING 000027 REC1 BY REC2 000028 FILLER BY MAST-NOTES. 000029C 01 MAST-REC1. 000030C 05 MAST-ACNO PIC 9(14). 000031C 05 MAST-IDNO PIC X(16). 000032C 05 MAST-NAME PIC X(35). 000033C 05 MAST-BALANCE PIC S9(13)V99 COMP-3. 000034C 05 MAST-REMARKS PIC X(38). 000035C 05 MAST-NOTES PIC X(39). 000036 * COPY REPLACING TEXT WORDS 000037 COPY FILREC4. 000038C 01 PIC-REC4. 000039C 05 PIC-ACNO PIC 9(14). 000040C 05 PIC-IDNO PIC X(16). 000041C 05 PIC-NAME PIC X(35). 000042C 05 PIC-BALANCE PIC S9(13)V99 COMP-3. 000043C 05 PIC-REMARKS PIC X(38). 000044C 05 FILLER PIC X(39). 000045 COPY FILREC4 REPLACING 000046 PIC BY MAST 000047 X BY Y 000048 9 BY 0. 000049C 01 PIC-REC4. 000050C 05 PIC-ACNO MAST 0(14). 000051C 05 PIC-IDNO MAST Y(16). 000052C 05 PIC-NAME MAST Y(35). 000053C 05 PIC-BALANCE MAST S9(13)V99 COMP-3. 000054C 05 PIC-REMARKS MAST Y(38). 000055C 05 FILLER MAST Y(39). 000056 * NESTED COPY. 000057 COPY FILREC2. 000058C 01 MAST-REC2. 000059C 05 MAST-ACNO PIC 9(14). 000060C 05 MAST-IDNO PIC X(16). 000061C 05 MAST-NAME PIC X(35). 000062C 05 MAST-BALANCE PIC S9(13)V99 COMP-3. 000063C 05 MAST-REMARKS PIC X(38). 000064C 05 MAST-SLOGAN PIC X(39). 000065C COPY CMBWORDS. 000066C 88 CMBWORD1 VALUE 'CMB IS THE BEST!'. 000067C 88 CMBWORD2 VALUE 'CMB ALWAYS FOR YOU!'. 000068C 88 CMBWORD3 VALUE 'CMB IS AMAZING!'. 000069C 88 CMBWORD4 VALUE 'CMB ALWAYS GO WITH YOU!'. 000070 * COPY REPLACING PSEUDO TEXT1 000071 COPY FILREC3. 000072C 01 :MAST-:REC3. 000073C 05 :MAST-:ACNO PIC 9(14). 000074C 05 :MAST-:IDNO PIC X(16). 000075C 05 :MAST-:NAME PIC X(35). 000076C 05 :MAST-:BALANCE PIC S9(13)V99 COMP-3. 000077C 05 :MAST-:REMARKS PIC X(38). 000078C 05 FILLER PIC X(39). 000079 COPY FILREC3 REPLACING ==:MAST-:== BY ==MST-==. 000080C 01 MST-REC3. 000081C 05 MST-ACNO PIC 9(14). 000082C 05 MST-IDNO PIC X(16). 000083C 05 MST-NAME PIC X(35). 000084C 05 MST-BALANCE PIC S9(13)V99 COMP-3. 000085C 05 MST-REMARKS PIC X(38). 000086C 05 FILLER PIC X(39). 000087 * COPY REPLACING PSEUDO TEXT2 000088 COPY FILREC3 REPLACING ==:MAST-:== BY ==WS-==. 000089C 01 WS-REC3. 000090C 05 WS-ACNO PIC 9(14). 000091C 05 WS-IDNO PIC X(16). 000092C 05 WS-NAME PIC X(35). 000093C 05 WS-BALANCE PIC S9(13)V99 COMP-3. 000094C 05 WS-REMARKS IC X(38). 000095C 05 FILLER PIC X(39). 000096 * COPY REPLACING PSEUDO TEXT3 000097 COPY FILREC3 REPLACING ==:MAST-:== BY ====. 000098C 01 REC3. 000099C 05 ACNO PIC 9(14). 000100C 05 IDNO PIC X(16). 000101C 05 NAME PIC X(35). 000102C 05 BALANCE PIC S9(13)V99 COMP-3. 000103C 05 REMARKS PIC X(38). 000104C 05 FILLER PIC X(39). 000105 * COPY SUPPRESS 000106 COPY FILREC1 SUPPRESS. 000114 * 000115 PROCEDURE DIVISION. 000116 * 000117 DISPLAY 'FOR TEST COPY VERB... ' 000118 STOP RUN.