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

时间:2018-03-12 14:25:59

标签: ibm-midrange rpgle

我在报告生成程序中使用固定格式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&lt;&gt;第一个片段中的SVCLTH和WOCLTH&lt;&gt;第二个片段中的WOCLTHsave是我需要添加到Break逻辑的附加条件。

当我尝试以固定格式(最后一行)添加此条件时,报告记录以无意的方式发生了变化。有人也可以指出下面的问题吗?

 *   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    

3 个答案:

答案 0 :(得分:3)

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

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

由于AND优先于OR,我会像这样添加parens:

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

从而解释为什么你得到的结果与你对自由形式版本的预期不同。

使用传统的固定格式IFxx操作码很难处理复杂的IF,你为什么要打扰?

即使是固定格式,也可以使用带有扩展因子2的IF

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

答案 1 :(得分:1)

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)

答案 2 :(得分:0)

这几乎肯定是运算符优先级的问题。运算符'和'的优先级高于运算符'或',因此无需对最后一个代码块进行分组,等效的自由格式为:

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

这与您的预期不符。我不是特别流利的固定格式RPG,所以我不知道你是否可以使用括号来修复固定格式代码中的问题,但这可以让你知道这个问题。