根据网上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.