Editeur D'expression (encore un)

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
microdevweb
Messages : 1800
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Editeur D'expression (encore un)

Message par microdevweb »

Aller j'y vais également de ma petite version :roll:

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()
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Editeur D'expression (encore un)

Message par Kwai chang caine »

L'exemple donné marche nickel ici, apparement les espaces sont interdits

Ensuite j'ai rajouté une soustraction "70*4+(40*8)-22" au pif et ..
Résultat Expression 1: -578
Verif Expression 1: 578
J'ai cassé la machine :oops:
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Répondre