将固定格式 RPG 转换为自由格式

Converting fixed format RPG to Free format

我在报告生成程序中用固定格式 RPG 编写了以下代码。我试过以自由格式重写它。检查前后生成的报告似乎相同。但是,如果其中有任何错误,请告诉我。

 *                                                 
 *   CONTROL BREAK WITHIN SOLIDS OR PATTERNS       
 *                                                 
C*    WOSRT1        IFEQ      '1'                  
C*    WOBKCL        ANDNE     SVCOLR               

C*    WOSRT1        OREQ      '2'                  
 ****       WOPATT    ANDNESVPATT                  
C*    WOCLT#        ANDNE     SVCLT#               

等效:

If ( (WOSRT1 = '1' and WOBKCL <> SVCOLR) or                          
     (WOSRT1 = '2' and ( WOCLT# <>  SVCLT# or WOCLTH <> SVCLTH )) ); 

代码片段 - 2:

 *   CONTROL BREAK WITHIN SOLIDS OR PATTERNS     
 C*    WOSRT1        IFEQ      '1'                
 C*    WOBKCL        ANDNE     WOBKCLsave         

 C*    WOSRT1        OREQ      '2'                
 C*    WOCLT#        ANDNE     WOCLT#save         

等效:

If ( (WOSRT1 = '1' and WOBKCL <> WOBKCLsave) or    
     (WOSRT1 = '2' and ( WOCLT# <>  WOCLT#save     
                      or WOCLTH <> WOCLTHsave ))); 

第一个代码段中的条件 WOCLTH <> SVCLTH 和第二个代码段中的 WOCLTH <> WOCLTHsave 是我需要添加到中断逻辑的附加条件。

当我尝试以固定格式(最后一行)添加此条件时,报告记录被意外更改。请有人也能指出下面的错误吗?

 *   CONTROL BREAK WITHIN SOLIDS OR PATTERNS
C     WOSRT1        IFEQ      '1'           
C     WOBKCL        ANDNE     WOBKCLsave    

C     WOSRT1        OREQ      '2'           
C     WOCLT#        ANDNE     WOCLT#save    
C     WOCLTH        ORNE      WOCLTHsave    

RDi 中的自由格式转换器将其转换为:

   IF WOSRT1 = '1'
   AND WOBKCL <> WOBKCLsave
   OR WOSRT1 = '2'
   AND WOCLT# <> WOCLT#save
   OR WOCLTH <> WOCLTHsave;

因为 AND 优先于 OR,我会像这样添加括号:

   IF (WOSRT1 = '1'
       AND WOBKCL <> WOBKCLsave)
   OR  (WOSRT1 = '2'
        AND WOCLT# <> WOCLT#save)
   OR WOCLTH <> WOCLTHsave;

从而解释了为什么您得到的结果与 free-form 版本的预期不同。

复杂的 IF 很难使用传统的固定格式 IFxx op-codes,你为什么要费心?

即使是固定格式,您也可以将 IF 与扩展因子 2 一起使用

 C                   IF        ( (WOSRT1 = '1' and WOBKCL <> SVCOLR)                           
 C                               OR (WOSRT1 = '2'   
 C                                   and ( WOCLT# <>  SVCLT#  
 C                                         or WOCLTH <> SVCLTH   
 C                                       )                       
 C                                  )                             
 C                             )                                   
 C                   endif

这几乎可以肯定是运算符优先级的问题。运算符 'And' 比运算符 'Or' 具有更高的优先级,因此无需对最后一个代码块进行任何分组,等效的自由格式为:

If (WORSRT = '1' And WOBKCL <> WOBKCLsave) Or
   (WOSRT1 = '2' And WOCLT# <> WOCLT#save) Or
   (WOCLTH <> WOCLTHsave);

这与您的预期不符。我对固定格式 RPG 不是特别熟练,所以我不知道您是否可以使用括号来解决固定格式代码中的问题,但这应该让您了解问题。

Charles 的回答是最好的,因为带括号的显式优先级比固定格式的隐式优先级更容易阅读,并且你不应该再使用固定格式。但是,要以没有扩展运算符的旧式固定格式做你想做的事,你必须这样做:

 *   CONTROL BREAK WITHIN SOLIDS OR PATTERNS
C     WOSRT1        IFEQ      '1'           
C     WOBKCL        ANDNE     WOBKCLsave    

C     WOSRT1        OREQ      '2'           
C     WOCLT#        ANDNE     WOCLT#save    

C     WOSRT1        OREQ      '2'           
C     WOCLTH        ORNE      WOCLTHsave



tl/dr;
如果您分解括号表达式中的最后一个条件

(WOSRT1 = '2' and ( WOCLT# <>  WOCLT#save or WOCLTH <> WOCLTHsave ))

你有 A and (B or C)。旧式固定格式 RPG 的问题是您不能将 OR 放在括号中。您需要重写它,以便用括号括起 AND。幸运的是,AND 是关联的,因此您可以将其写为 (A and B) or (A and C).