String Evaluation
Posted in 1998
This is a multi-part message in MIME format. ------=_NextPart_000_0005_01BDEB9F.2B0335C0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit I have two functions, one is database independent (mth_eval.4gl) and the other one could be more efficient and support more operators, but is database dependent (mth_evaldbs.4gl). Choose which is better for you. Any comments or suggestions is welcome! Ing. Melvin Perez Cedano Vicepresidente Tecnico CAM Informatica, S. A. ------=_NextPart_000_0005_01BDEB9F.2B0335C0 Content-Type: application/octet-stream; name="mth_eval.4gl" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="mth_eval.4gl" --***********************************************************************= ***** --* Modulo : mth_eval.4gl --* --* Descripcion :=20 --* @(#) Este fuente contiene la logica para evaluar expresiones = aritmeticas. --* @(#) Este evaluador soporta las cuatro operaciones aritmeticas = basicas: --* @(#) Suma (+) --* @(#) Resta (-) --* @(#) Producto (*) --* @(#) Division (/) --* @(#) --* @(#) Actualmente este evaluador no realiza analisis sintactico de la = --* @(#) expresion, por lo que la expresion especificada no debe = contener=20 --* @(#) espacios en blanco, los parentesis deben estar balanceados, y = debe=20 --* @(#) haber correspondencia entre el numero de operandos y = operadores. --* --* Funciones : fgl_eval() --* --* SCCS Id No. : @(#)mth_eval.4gl 1.2 --* Autor : Ing. Melvin Perez Cedano --* Fecha : 4/17/97 17:25:24 --* Path : /mant/infogen/lib.4gm/SCCS/math.std/s.mth_eval.4gl --* --* El uso, modificacion o duplicacion total o parcial del contenido de = este --* archivo esta limitado por el acuerdo de adquisicion. --* --* (C) 1996 CAM Informatica, S. A. --* Todos los Derechos Reservados. --***********************************************************************= ***** {------------------------------------------------------------------------= ----} --> Definicion de variables estaticas del modulo. DEFINE=20 --> Stack conteniendo los operandos de la expresion Num_Stack RECORD nextitem SMALLINT, items ARRAY[100] OF FLOAT END RECORD, NumSet CHAR(13), OprSet CHAR(10), infija, postfija ARRAY[100] OF CHAR(16), Opr_Stack CHAR(256), NextItem, LastItemIf, LastItemPf SMALLINT --***********************************************************************= ***** --* Funcion : @(#) fgl_eval() --* --* Descripcion :=20 --* @(#) Esta funcion evalua una expresion aritmetica utilizando el = metodo de --* @(#) polaca invertida (reverse Polish) y retorna el resultado. --* @(#) Este evaluador soporta las cuatro operaciones aritmeticas = basicas: --* @(#) Suma (+) --* @(#) Resta (-) --* @(#) Producto (*) --* @(#) Division (/) --* @(#) --* @(#) Actualmente este evaluador no realiza analisis sintactico de la = --* @(#) expresion, por lo que la expresion especificada no debe = contener=20 --* @(#) espacios en blanco, los parentesis deben estar balanceados, y = debe=20 --* @(#) haber correspondencia entre el numero de operandos y = operadores. --* --* Parametros : p_expresion Expresion a resolver. --* --* Retorno : Resultado de la expresion. --* --* Globales : n/a --* --* Forms : n/a --* --* Autor : Ing. Melvin Perez Cedano --***********************************************************************= ***** {------------------------------------------------------------------------= ----} FUNCTION fgl_eval(p_expresion) DEFINE p_expresion CHAR(256) CALL Init_eval() CALL ReversePolish(p_expresion) RETURN calcula() END FUNCTION --***********************************************************************= ***** --* Init_eval() --* --* Esta funcion inicializa las variables globales del modulo. --***********************************************************************= ***** {------------------------------------------------------------------------= ----} FUNCTION Init_eval() LET NumSet=3D"[.0123456789]" LET OprSet=3D"[+-*/^%]" LET LastItemPf =3D 1 LET LastItemIf =3D 0 LET Num_Stack.NextItem =3D 101 LET Opr_Stack =3D "+" CALL PushStack(0) END FUNCTION --***********************************************************************= ***** --* ReversePolish() --* --* Esta funcion toma la expresion en notacion Infija y la convierte a = su --* equivalente PostFija o Polaca Inversa. --* --* Argumentos: --* <ninguno> --* Retorno : --* <ninguno> --***********************************************************************= ***** {------------------------------------------------------------------------= ----} FUNCTION ReversePolish(p_expresion) DEFINE p_expresion CHAR(256), i, n , l, p SMALLINT, chr CHAR(1) LET i =3D 1 --> Pone la expresion recibida como una cadena en un arreglo, --> poniendo de en cada elemento del arreglo un operador o un = operando. CALL MakeInfija(p_expresion) LET n =3D LastItemIf --> Recorre la Infija y crea la PostFija WHILE i <=3D n LET l =3D LENGTH(Infija[i]) --> Toma el ultimo caracter de la cadena para determinar su = contenido LET chr=3DInfija[i][l] CASE=20 --> Si es un operando. WHEN chr MATCHES NumSet LET PostFija[LastItemPf] =3D Infija[i] LET LastItemPf =3D LastItemPf + 1 --> Si es un operador. WHEN chr =3D "+" OR chr =3D "-" OR chr =3D "*" OR chr =3D = "/" CALL PushOperator(i) --> Condiciones especiales para los Parentesis WHEN chr =3D "(" LET Opr_Stack =3D Opr_Stack CLIPPED, "(" WHEN chr =3D ")" CALL CloseParenthesis() END CASE LET i =3D i + 1 END WHILE --> Concatena los operandores restantes en la Opr_Stack. CALL finish() END FUNCTION --***********************************************************************= ***** --* MakeInfija() --*=20 --* Esta funcion pone la cadena o expresion especificada en un arreglo. --* En cada posicion del arreglo se encuentra un Operando o un Operador. --* --* Argumentos: --* p_expresion Expresion a procesar. --***********************************************************************= ***** {------------------------------------------------------------------------= ----} FUNCTION MakeInfija(p_expresion) DEFINE p_expresion CHAR(256), lf_negative,@@NL