【ABAP】算数表达式

根据网上JAVA的代码改的,具体哪篇忘了。。。
主要逻辑是中缀表达式转后缀表达式

FORM check_formula USING p_mark CHANGING p_formula." flag.

  CHECK error_flag = ''.
  CHECK p_formula IS NOT INITIAL.

*  flag = 'X'.
*  CLEAR error_flag.

  REFRESH t_code.

  " 解析公式
  CLEAR l.
  l = STRLEN( p_formula ).

  j = 0.
  k = 0.
  CLEAR: ch1,ch2.
  DO l TIMES.
    ch1 = ch2.
    ch2 = p_formula+j(1).
    j = j + 1.

    IF ch2 NE ''.
*      IF ch2 = 'L' OR ch2 = 'W' OR ch2 = 'H'.
*        CONTINUE.
*      ENDIF.

      IF ch1 = 'L' OR ch1 = 'W' OR ch1 = 'H'.
        IF cl_abap_matcher=>matches(
                  pattern = '^\d'
                     text = ch2 ) = abap_true.
          READ TABLE t_code INDEX k.
          IF sy-subrc = 0.
            CONCATENATE t_code-ch ch2 INTO t_code-ch.
            MODIFY t_code INDEX k.
          ENDIF.
          CONTINUE.

        ELSE.
          IF ch2 = '+' OR ch2 = '-' OR ch2 = '*' OR ch2 = '/' OR ch2 = ')'.
            "...
          ELSE.
            error_flag = 'X'.
            EXIT.
          ENDIF.
        ENDIF.
      ELSEIF cl_abap_matcher=>matches(
                 pattern = '^\d'
                    text = ch1 ) = abap_true OR ch1 = '.'.

        IF cl_abap_matcher=>matches(
                 pattern = '^\d'
                    text = ch2 ) = abap_true OR ch2 = '.'.
          READ TABLE t_code INDEX k.
          IF sy-subrc = 0.
            CONCATENATE t_code-ch ch2 INTO t_code-ch.
            MODIFY t_code INDEX k.
          ENDIF.
          CONTINUE.
        ENDIF.
      ENDIF.

      CLEAR t_code.
      t_code-ch = ch2.
      APPEND t_code.
      k = k + 1.
    ENDIF.
  ENDDO.


  IF error_flag = ''.
    error_flag = 'X'.
    LOOP AT t_code WHERE ch+0(1) = p_mark.
      error_flag = ''.
      EXIT.
    ENDLOOP.

    IF error_flag = ''.

      PERFORM dotrans.
      PERFORM doparse.

    ENDIF.

    IF error_flag = 'X'.
      IF r1 = 'X'.
        CLEAR l_msg.
        CONCATENATE '公式' ls_out1-fid '错误' INTO l_msg.
      ELSEIF r2 = 'X'.
        CLEAR l_msg.
        CONCATENATE '公式' p_formula '错误' INTO l_msg.
      ENDIF .
      MESSAGE l_msg TYPE 'I'.
      EXIT.
    ENDIF.

    " 规范公式格式
    CLEAR p_formula.
    LOOP AT t_code.
      CONCATENATE p_formula t_code-ch INTO p_formula SEPARATED BY space.
    ENDLOOP.

  ENDIF.

ENDFORM.   
FORM dotrans.

  DATA: lv_len(30) TYPE c,
        lv_wid(30) TYPE c,
        lv_hig(30) TYPE c.

  IF r1 = 'X' OR r2 = 'X'.
    lv_len = '1'.
    lv_wid = '1'.
    lv_hig = '1'.
  ELSEIF r4 = 'X'.
    " ...
  ENDIF.

  REFRESH: t_stacka,t_stackb.

  LOOP AT t_code.

    CASE t_code-ch.
      WHEN '+' OR '-'.
        PERFORM gotopre USING t_code-ch 1.
      WHEN '*' OR '/'.
        PERFORM gotopre USING t_code-ch 2.
      WHEN '('.
        PERFORM stackpush TABLES t_stackb USING t_code-ch.
      WHEN ')'.
        PERFORM gotparen.
      WHEN OTHERS.

        IF r1 = 'X' OR r2 = 'X'.
          IF t_code-ch+0(1) = 'L' .
            t_code-ch = lv_len.
            CONDENSE t_code-ch NO-GAPS.
          ELSEIF t_code-ch+0(1) = 'W'.
            t_code-ch = lv_wid.
            CONDENSE t_code-ch NO-GAPS.
          ELSEIF t_code-ch+0(1) = 'H'.
            t_code-ch = lv_hig.
            CONDENSE t_code-ch NO-GAPS.
          ENDIF.
        ELSEIF r4 = 'X'.
          IF t_code-ch CS 'L' OR t_code-ch CS 'W' OR t_code-ch CS 'H'.
            CLEAR w_prmtr.
            READ TABLE t_prmtr INTO w_prmtr WITH KEY prmtr = t_code-ch.
            IF sy-subrc = 0.
              t_code-ch = w_prmtr-value.
              IF t_code-ch IS INITIAL.
                t_code-ch = '0'.
              ENDIF.
            ENDIF.
          ENDIF.
        ENDIF.

*        IF cl_abap_matcher=>matches(
*                 pattern = '([1-9]\d*)|0'
*                    text = t_code-ch ) = abap_false.
*          error_flag = 'X'.
*          RETURN.
*        ENDIF.

        TRY.
            num_p = t_code-ch.
          CATCH cx_sy_conversion_no_number.
            error_flag = 'X'.
            RETURN.
        ENDTRY.

        PERFORM stackpush TABLES t_stacka USING t_code-ch.

    ENDCASE.
  ENDLOOP.

  LOOP AT t_stackb.
    PERFORM stackpush TABLES t_stacka USING t_stackb-ch.
    DELETE t_stackb.
  ENDLOOP.

ENDFORM.
FORM gotopre USING ch2 prec2.

  DATA: prec1   TYPE i.
*  DATA: prec2   TYPE i.
  DATA: ch1(30) TYPE c.
*  DATA: ch2(30) TYPE c.

*  ch2 = ch.
*  prec2 = prec.

  IF t_stackb[] IS NOT INITIAL.

    PERFORM stackpop TABLES t_stackb CHANGING ch1.

    IF ch1 = '('.
      PERFORM stackpush TABLES t_stackb USING ch1.
      PERFORM stackpush TABLES t_stackb USING ch2.
    ELSE.

      IF ch1 = '+' OR ch1 = '-'.
        prec1 = 1.
      ELSEIF ch1 = '*' OR ch1 = '/'.
        prec1 = 2.
      ENDIF.

      IF prec2 > prec1.
        PERFORM stackpush TABLES t_stackb USING ch1.
        PERFORM stackpush TABLES t_stackb USING ch2.
      ELSE.
        PERFORM stackpush TABLES t_stacka USING ch1.
        PERFORM stackpush TABLES t_stackb USING ch2.
      ENDIF.

    ENDIF.

  ELSE.
    PERFORM stackpush TABLES t_stackb USING ch2.
  ENDIF.

ENDFORM.  
FORM stackpop TABLES t_stack STRUCTURE t_code
             CHANGING ch.

*  CLEAR l.
*  DESCRIBE TABLE t_stack LINES l.
  READ TABLE t_stack INDEX 1.
  IF sy-subrc = 0.
    ch = t_stack-ch.
    DELETE t_stack INDEX 1.
  ENDIF.

ENDFORM.
FORM stackpush TABLES t_stack STRUCTURE t_code
                USING ch.

  CLEAR t_stack.
  t_stack-ch = ch.
  INSERT t_stack INDEX 1.

ENDFORM. 
FORM gotparen.

  LOOP AT t_stackb.

    IF t_stackb-ch = '('.
      DELETE t_stackb.
      EXIT.
    ENDIF.
    PERFORM stackpush TABLES t_stacka USING t_stackb-ch.
    DELETE t_stackb.

  ENDLOOP.

ENDFORM. 
FORM doparse.

  DATA: ch(30) TYPE c.

  REFRESH t_codein.

  LOOP AT t_stacka.
    CLEAR t_codein.
    MOVE t_stacka TO t_codein.
    INSERT t_codein INDEX 1.
  ENDLOOP.

  REFRESH t_codeout.
  LOOP AT t_codein.

    IF t_codein-ch = '+' OR t_codein-ch = '-' OR t_codein-ch = '*' OR t_codein-ch = '/'.
      PERFORM stackpop TABLES t_codeout CHANGING ch2.
      PERFORM stackpop TABLES t_codeout CHANGING ch1.
      CLEAR ch.

      CASE t_codein-ch.
        WHEN '+'.
          num_p1 = ch1.
          num_p2 = ch2.
          num_p = ch1 + ch2.
          ch = num_p.
*          ch = ch1 + ch2.
          CONDENSE ch NO-GAPS.
          PERFORM stackpush TABLES t_codeout USING ch.
        WHEN '-'.
          num_p1 = ch1.
          num_p2 = ch2.
          num_p = ch1 - ch2.
          ch = num_p.
*          ch = ch1 - ch2.
          CONDENSE ch NO-GAPS.
          PERFORM stackpush TABLES t_codeout USING ch.
        WHEN '*'.
          num_p1 = ch1.
          num_p2 = ch2.
          num_p = ch1 * ch2.
          ch = num_p.
*          ch = ch1 * ch2.
          CONDENSE ch NO-GAPS.
          PERFORM stackpush TABLES t_codeout USING ch.
        WHEN '/'.
          num_p1 = ch1.
          num_p2 = ch2.
          num_p = ch1 / ch2.
          ch = num_p.
*          ch = ch1 / ch2.
          CONDENSE ch NO-GAPS.
          PERFORM stackpush TABLES t_codeout USING ch.
      ENDCASE.

    ELSE.
      CLEAR t_codeout.
      MOVE t_codein TO t_codeout.
      INSERT t_codeout INDEX 1.
    ENDIF.

  ENDLOOP.

ENDFORM. 

你可能感兴趣的:(abap)