嵌套执行需要并且不需要结束执行

Nested perform needs and doesn't need an end-perform

使用这段代码,我得到

16: Perform stmnt not terminated by end-perform

33: syntax error, unexpected end-perform

为什么说我需要结束表演又不需要呢?

   identification division.
   program-id.  xxx.     
  * will accept and display a num until 0 is called then
  * asks to go again


   data division.
   file section.

   working-storage section.     
   01  num                 pic 9(4).
   01  hold                pic 9(4).
   01  another             pic x.
   procedure division.
     perform until another = 'N'                 (line 16)
        Display "Another Session (Y/N)? "
              with no advancing
        if another = 'Y'
        Display "Enter a 4-digit unsigned number (0 to stop): "
             with no advancing
        accept num
        move num to hold
        perform until num = 0
        Display "Enter a 4-digit unsigned number (0 to stop): "
             with no advancing
        accept num
          if num <> 0
       move num to hold
        end-perform.
        display space
        Display "The last number entered: "hold
     End-perform.                            (Line 33)

     stop run.
   end-perform.
    display space
    Display "The last number entered: "hold
 End-perform.                            (Line 33)

杀手就是full-stop/period(第30行)。

尽管自从 1985 年标准 COBOL 对 full-stops/periods 放松了很多,一个单一的标准就会让所有当前的范围尖叫停止。您可以嵌套 50 层深,一个 full-stop/period 可以一举结束它们。

我的建议是在程序部分使用 full-stop/period 的绝对最小值。

即:一终止PROCEDURE DIVISION头;一个终止每个 paragraph/SECTION 标签;一个终止一个paragrpah/SECTION;一个终止程序(对于没有 paragraphs/SECTIONS 的程序)。此外,如果您有 PROCEDURE DIVISION COPY 或 REPLACE 语句,则需要 full-stops/periods 来终止它们。

除了标签的终止,我把每个 full-stop/period 都放在一行上,从不附加任何代码。然后我可以移动代码并插入代码,而不必担心我是否需要 add/remove a full-stop/period.

至于为什么需要END-PERFORM,是"inline PERFORM"。从句法上讲,内联 PERFORM 需要一个 END-PERFORM,但是您使用 full-stop/period 导致在找到 END-PERFORM 之前终止 PERFORM 范围,因此第 16 行出现错误。随后 END-PERFORM 未连接到PERFORM 被定位,所以第 33 行的错误。

在您的问题中放置错误消息时,请务必完全按照您看到的那样包含错误消息。 Copy/paste,请不要重试。也包括任何消息编号。

绝对不能混用句号“.”来自 Cobol-74 的范围终止符和来自 Cobol-85 的 End-* 范围终止符。

区别在于句号“.”终止所有范围。

End-* 仅终止最近的作用域,正如您所期望的那样。

放置一个“.”在带有 End-* 的代码中间有点像在它的中间投下一颗核弹。通常,对于上个四分之一世纪左右制作的编译器,句号应该只出现在段落名称末尾的过程部分中,或者出现在段落末尾(和节也一样,但那些在分段和覆盖由操作系统管理的时代)。我喜欢使用 "EXIT." 或 "CONTINUE." 只是为了强调我在程序部门中使用了 bad-nasty-best-avoided-periods 之一。