a noter qu'il doit être peaufiné car il ne fonctionnera pas correctement avec des divisions qui déboucherons sur des flottant etc ... Mais ce code peut donner des idées
Fonctionne avec un système de pile LIFO.
Code : Tout sélectionner
DeclareModule Resolve
;================================================================================================================
; Resolve
; ----------------------------------------------------------------------------------------------------------------
; :Input : Chaine de caractères contenant l'expression à résoudre
;
; :Output : un entier long qui retourne : 0 l'opération a échouée
; : 1 le résultat est un entier (poura être retourner avec GetIntResult
; : 2 PAS ENCORE IMPLEMENTE
;
; :PROCESS : Résout une espression matémathique simple
;
; :RESTRICTED : Seul les entiers sont actuelement acceptés
; : Les expressions acceptées sont '0123456789' '+' '-' '*' '/' '(' ')'
Declare.l Resolve(Chaine.s)
; ----------------------------------------------------------------------------------------------------------------
;================================================================================================================
; GetPositionError
; ----------------------------------------------------------------------------------------------------------------
; :Input : void
;
; :Output : un entier long avec la position dans la chaine ou un erreur est détectée
;
; :PROCESS : retourne position dans la chaine ou un erreur est détectée
;
Declare.l GetPositionError()
; ----------------------------------------------------------------------------------------------------------------
;================================================================================================================
; GetUnavailableLetter
; ----------------------------------------------------------------------------------------------------------------
; :Input : void
;
; :Output : Le caractère ASCII non reconnu
;
; :PROCESS : retourne Le caractère ASCII non reconnu
;
Declare.c GetUnavailableLetter()
; ----------------------------------------------------------------------------------------------------------------
;================================================================================================================
; GetIntResult
; ----------------------------------------------------------------------------------------------------------------
; :Input : void
;
; :Output : Le résultat en entier long
;
; :PROCESS : retourne Le résultat en entier long
;
Declare.l GetIntResult()
; ----------------------------------------------------------------------------------------------------------------
EndDeclareModule
Module Resolve
EnableExplicit
;================================================================================================================
;-* Grammaire et priorité
; ----------------------------------------------------------------------------------------------------------------
; '()'
; '* /'
; '+ -'
;}
;================================================================================================================
;-* CONSTANTES
; ----------------------------------------------------------------------------------------------------------------
Enumeration
#IntType
EndEnumeration
;}
;================================================================================================================
;-* STRUCTURE
; ----------------------------------------------------------------------------------------------------------------
;}
;================================================================================================================
;-* PRIVATE VARIABLES
; ----------------------------------------------------------------------------------------------------------------
Global NewList myPile.l() ; Pile LIFO
Global.l crtCar=1,ErrorPos
Global.s Expression
Global.c UnavailableCaractere
;}
;================================================================================================================
;-* PRIVATE PROTOTYPES
; ---------------------------------------------------------------------------------------------------------------
Declare AddSub()
Declare MulDivide()
Declare Factor()
Declare Number()
Declare DecimalNumber()
Declare NextCaratere()
Declare.c CurrentCaractere()
Declare PushPile(value.l)
Declare.l PopPile()
Declare IsDigit()
;}
;================================================================================================================
;-* PRIVATE FUNCTIONS
; ---------------------------------------------------------------------------------------------------------------
Procedure AddSub()
;**************************************************************************************************************
; INPUT : void
;
; OUTPUT : void
;
; PROCESS : recherche de caractère + -
;**************************************************************************************************************
Protected.l Res,Op1,Op2
MulDivide()
While CurrentCaractere()='+' Or CurrentCaractere()='-'
Select CurrentCaractere()
Case '+'
NextCaratere()
MulDivide()
Op1=PopPile()
Op2=PopPile()
Res=Op1+Op2
PushPile(Res)
Case '-'
NextCaratere()
MulDivide()
Op1=PopPile()
Op2=PopPile()
Res=Op1-Op2
PushPile(Res)
EndSelect
Wend
EndProcedure
Procedure MulDivide()
Protected.l Res,Op1,Op2
Factor()
While CurrentCaractere()='*' Or CurrentCaractere()='/'
Select CurrentCaractere()
Case '*'
NextCaratere()
Factor()
Op1=PopPile()
Op2=PopPile()
Res=Op1*Op2
PushPile(Res)
Case '/'
NextCaratere()
Factor()
Op1=PopPile()
Op2=PopPile()
Res=Op1/Op2
PushPile(Res)
EndSelect
Wend
EndProcedure
Procedure Factor()
If CurrentCaractere()='('
NextCaratere()
AddSub()
If CurrentCaractere()=')'
NextCaratere()
EndIf
Else
Number()
EndIf
EndProcedure
Procedure Number()
; La fonction acceptera par après des binaires et hexa
DecimalNumber()
EndProcedure
Procedure DecimalNumber()
Protected.l val=0
While IsDigit()
val=(val *10 ) + (CurrentCaractere() - $30)
NextCaratere()
Wend
PushPile(val)
EndProcedure
Procedure NextCaratere()
crtCar+1
EndProcedure
Procedure.c CurrentCaractere()
Protected car.s
car=Mid(Expression,crtCar,1)
ProcedureReturn Asc(car)
EndProcedure
Procedure PushPile(value.l)
AddElement(myPile())
myPile()=value
EndProcedure
Procedure.l PopPile()
Protected Value.l
LastElement(myPile())
Value=myPile()
DeleteElement(myPile())
ProcedureReturn Value
EndProcedure
Procedure IsDigit()
Select CurrentCaractere()
Case '0','1','2','3','4','5','6','7','8','9'
ProcedureReturn #True
Default
ProcedureReturn #False
EndSelect
EndProcedure
;}
;================================================================================================================
;-* PUBLIC FUNCTIONS
; ----------------------------------------------------------------------------------------------------------------
Procedure.l Resolve(Chaine.s)
ClearList(myPile())
Expression=Trim(Chaine)+Chr(0)
AddSub()
If CurrentCaractere()=0
ProcedureReturn 1
Else
UnavailableCaractere=CurrentCaractere()
ErrorPos=crtCar
ProcedureReturn 0
EndIf
EndProcedure
Procedure.l GetPositionError()
ProcedureReturn ErrorPos
EndProcedure
Procedure.c GetUnavailableLetter()
ProcedureReturn UnavailableCaractere
EndProcedure
Procedure.l GetIntResult()
LastElement(myPile())
ProcedureReturn myPile()
EndProcedure
;}
EndModule
Global.s Exp1="70*4+(40*8)"
Global.l res1=0
ver1=70*4+(40*8)
; If Resolve::Resolve(Exp1)
; res1=Resolve::GetIntResult()
; EndIf
If Resolve::Resolve(Exp1)
res1=Resolve::GetIntResult()
EndIf
OpenConsole("Teste")
PrintN("Résultat Expression 1: "+Str(res1))
PrintN("Verif Expression 1: "+Str(ver1))
Input()
CloseConsole()