Token

Programmation d'applications complexes
Aranoth
Messages : 293
Inscription : sam. 24/janv./2004 12:00
Localisation : Toulouse (31)
Contact :

Token

Message par Aranoth »

Dans le but de décortiquer une ligne, j'ai cherché les Tokens dans PureBASIC mais sans résultat...l'aide n'affiche rien dessus...

ce que j'aimerait c'est que mon programme découpe chaque ligne d'un fichier par mot et les examines.

Savez vous comment utiliser les tokens ?

merci d'avance :wink:
filperj
Messages : 395
Inscription : jeu. 22/janv./2004 1:13

Message par filperj »

Avec stringfield, en mettant un espace comme délimiteur, ça le fait pas ?
StringField()

Syntaxe

Resultat$ = StringField(Chaine$, Index, Delimiteur$)
Description

Retourne un champ d'une chaine à l'index spécifié. 'Delimiteur$' est le caractère choisi comme séparateur des champs de la chaine (un seul caractère de longueur autorisée). La première position de 'Index' est 1.

Exemple:
For k=1 To 7
Debug StringField("Je suis une chaine contenant des champs", k, " ")
Next

OS Supportés

Windows, AmigaOS, Linux
Si j'ai bien compris ta question... :roll:
Le chaos l'emporte toujours sur l'ordre
parcequ'il est mieux organisé.
(Ly Tin Wheedle)
Aranoth
Messages : 293
Inscription : sam. 24/janv./2004 12:00
Localisation : Toulouse (31)
Contact :

Message par Aranoth »

ca m'a l'air de faire l'affaire,

mais dans le cas du k=7, il faudrait faire:

Code : Tout sélectionner

For k=1 To 7 
    Tableau$(k,1)=StringField("Je suis une chaine contenant des champs", k, " ") 
Next 
je pense que c'est ca, sinon on perd les infos au fur et a mesure non ?

Je te remercie beaucoup ! :)
Avatar de l’utilisateur
cederavic
Messages : 1338
Inscription : lun. 09/févr./2004 23:38
Localisation : Bordeaux

Message par cederavic »

le probleme c'est qu'il faut que tu sache combien il y a de mot dans ta phrase, si tu ne le sais pas, un bout de code tout simple

Code : Tout sélectionner

Procedure.l CountWord(Chaine.s, Delimiteur.s)
  h = 1
  For t = 0 To Len(Chaine)
    k.s = Mid(Chaine, t, 1)
    If k = Delimiteur
      h + 1
    EndIf
  Next
  ProcedureReturn h
EndProcedure

test.s = "salut ça va?"
For t = 1 To CountWord(test, " ")
  Debug StringField(test, t, " ")
Next

test = "sa_va_et_toi?"
For t = 1 To CountWord(test, "_")
  Debug StringField(test, t, "_")
Next
je sais qu'il existe une autre fonction dans ce genre optimiser en asm mai bon ça depanne bien ce ptit truc :)
Aranoth
Messages : 293
Inscription : sam. 24/janv./2004 12:00
Localisation : Toulouse (31)
Contact :

Message par Aranoth »

merci ca m'évite de faire tourner le programme dans le vide quand la chaine est finie :D
Aranoth
Messages : 293
Inscription : sam. 24/janv./2004 12:00
Localisation : Toulouse (31)
Contact :

Message par Aranoth »

Autre problème:

Maintenant je veut appliquer ma petite fonction sur un fichier, mais voir ca ligne par ligne

Donc je sais que je peut découper ligne par ligne si il y a un charactere après genre "fin de ligne"

Donc ma question: esce que le charactere ENTER a un identifiant ? ou doisje mettre une sorte de ";" après chaque ligne (ce qui serait embettant lol) ?
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

tu as le caratère chr(10) qui est le fin de ligne normal
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Patrick88
Messages : 1564
Inscription : mer. 21/janv./2004 18:24

Message par Patrick88 »

je m'interesse également à ce "genre de choses"...

regarde mon code..
c'est basé sur un source de basic écrit en C
chercher DDSBASIC sur google...
Tu peux également regarder du coté des pascals ecrit en pascal
pascal de Wirth par exemple (la base du turbo pascal de borland)
chercher 1975-Wirth ou 1975-PL-0 sur google
mais transformer du pascal en pb, c'est hard, vaut mieux partir d'un source C, c'est plus simple...

Code : Tout sélectionner

#LMAX = 9999
#VERSION = "Basic (console) v0.4 - 01/02/04"

Dim prog_source.s(#LMAX)
Global buffer.s 
Global numero_ligne.l
Global car.b

Procedure affiche_aide()
  PrintN("")
  PrintN(#VERSION)
  PrintN("")
  PrintN("Commande en mode immediat :")
  PrintN("")
  PrintN("RUN     LIST    NEW     LOAD "+Chr(34)+"filename"+Chr(34))
  PrintN("BYE     SAVE "+Chr(34)+"filename"+Chr(34)+"   HELP")
  PrintN("") 
  PrintN("Commandes de programmation :")
  PrintN("") 
  PrintN("PRINT "+Chr(34)+"string"+Chr(34))
  PrintN("CLS ")
  PrintN("") 
EndProcedure

Procedure.s ExtractString(texte.s)
  result.s = ""
  posit_guillemet.w = FindString(texte,Chr(34),1)
  For i = posit_guillemet To Len(texte)
    If Mid(texte,i,1)<>Chr(34)
      result = result+ Mid(texte,i,1)
    EndIf
  Next i
  ProcedureReturn result  
EndProcedure

Procedure StockLigneDeCode()
  CallDebugger 
  numero_ligne = Val(buffer)
  pos_debut_code.b = 0 
  exit_while.b = 0
  ; supprime la ligne dans la table
  If prog_source(numero_ligne)<>""
    prog_source(numero_ligne)=""
  EndIf
  ; place le restant de la ligne de code dans la table prog_source()
  pos_debut_code=1
  While exit_while=0
    car =Asc(Mid(buffer,pos_debut_code,1))
    If car>=48 And car<=57 
      pos_debut_code+1
    Else
      exit_while=1
    EndIf
  Wend
  prog_source(numero_ligne)=Mid(buffer,pos_debut_code,Len(buffer))
EndProcedure

If OpenConsole()
  sortie_programme.b = 0 
  prog_source(#LMAX) = "E" ; "END"
  affiche_aide()
  While sortie_programme = 0
    Print("> ")
    buffer = Input()
    PrintN("")
   
    car = Asc(UCase(Left(buffer,1)))
    Select car
      Case Asc("B") ; BYE = quitte le programme
        sortie_programme = 1
      Case Asc("C")
        ClearConsole()
        
      Case Asc("H")
        affiche_aide()
        
      Case Asc("L") ; LIST = liste le programme
        If UCase(Left(buffer,2)) = "LI"
          For numero_ligne = 0 To #LMAX-1
            If prog_source(numero_ligne )<>""
              PrintN (Str(numero_ligne )+" "+prog_source(numero_ligne )) ;
            EndIf
          Next numero_ligne 
        EndIf
        
        If UCase(Left(buffer,2)) = "LO"
          nomfichier.s = ExtractString(buffer)
          
          If OpenFile(0,nomfichier)
            buffer = ""
            While Lof()<>Loc()
              buffer = ReadString()  
              StockLigneDeCode()
            Wend
            CloseFile(0)
          EndIf  
        EndIf
          
      Case Asc("N")
        For numero_ligne = 0 To #LMAX 
          prog_source(numero_ligne ) = "" 
        Next numero_ligne 
        prog_source(#LMAX) = "E" ; "END"
       
      Case Asc("R") ; RUN = execute le programme
        CallDebugger
        numero_ligne = 0 : interpretation = 0
        ; tant qu'il y des lignes de code à executer
        While interpretation  = 0
          ; recherche dans la table la premiere ligne de code à executer
          While Len(prog_source(numero_ligne))=0
            numero_ligne+1 
            ;Debug Str(numero_ligne)+" "+prog_source(numero_ligne)
          Wend
          ligne_de_commande.s = prog_source(numero_ligne)
          ;; supprime espace avant et apres ligne de commande
          ligne_de_commande = LTrim(ligne_de_commande)
          ligne_de_commande = RTrim(ligne_de_commande)
          
          car.b = Asc(UCase(Left(ligne_de_commande,1)))
          Select car
            Case Asc("C")
              ClearConsole()
          
            Case Asc("P")
              If UCase(Left(ligne_de_commande,3)) = "PRI"
                ; affiche les caracteres apres les guillemets
                texte_a_afficher.s = ExtractString(ligne_de_commande)
                PrintN(texte_a_afficher)
              EndIf
            Case Asc("E")
              interpretation  = 1
          EndSelect

          numero_ligne+1 
        Wend
        
      Case Asc("S")
        nomfichier.s = ExtractString(buffer)
        
        If OpenFile(0,nomfichier)
          For numero_ligne  = 0 To #LMAX 
            If prog_source(numero_ligne )<>"" 
              WriteStringN(Str(numero_ligne)+prog_source(numero_ligne ) ) 
            EndIf
          Next numero_ligne 
          CloseFile(0)
        EndIf  
        
      Default
        StockLigneDeCode()
        
    EndSelect
  Wend

  CloseConsole()
EndIf
ça sauve des fichiers, ça les relits, ça les listes, ça les executes...

c'est une méthode de travail...

si tu jettes un oeil sur les source pascal, tu verras qu'il utilise, une fonction

Code : Tout sélectionner

Procedure.b CaractereSuivant(t.s)
  Result.b=0
  If Pos <= Len(t)
    car = Mid(t,Pos,1)
    If Pos < Len(t) ; lit un caractere en avance
      cadr = Mid(t,Pos+1,1)
      Result = 2
    EndIf
    Pos = Pos +1
    Result=1
  EndIf
  ProcedureReturn Result
EndProcedure
le principe :
pour chaque ligne de code, lire caractere par caractere
et s'arranger pour reconnaitre les symboles au fur et à mesures de leur apparition... ( j'ai essayé/explorer un peu toutes les méthodes(dont le stringfield) )

fais des recherches sur caractere suivant réalisation compilateur interpreteur .... je peux te passer mes sources si tu le souhaites ( mais il vaut mieux expérimenter par soi-même

pour les tokens, hum, c'est simple et complexe, ça a été inventé à l'époque des ordi qui avaient des petites mémoire ( zx81 1ko )
le token prenaient 1 octet en mémoire alors que la même instruction = autant de caractere = autant d'octet en moins pour le code...
pour le principe, je te conseille la page :

http://www.cix.co.uk/~rrussell/products ... nnexd.html

descend à "Program Storage in Memory"

voila de quoi t'occuper....

patrick
Aranoth
Messages : 293
Inscription : sam. 24/janv./2004 12:00
Localisation : Toulouse (31)
Contact :

Message par Aranoth »

Merci Soldat Inconnu et Patrick88, j'ai réalisé ce code (un interpreteur), mais il ne marche pas...il ne lit que la derniere ligne de mon fichier !

Code : Tout sélectionner

; INITIALISER



; DECLARER LES FONCTIONS
Declare.l CountWord(Chaine.s, Delimiteur.s)


; TABLEAUX
Dim CODE$(200, 200)
Dim PAGE$(200)
CHAR = 1


; CHARGER LE FICHIER SOURCE
ReadFile(1, "essai.txt")
UseFile(1)

; DECOUPER LES LIGNES
For F = 1 To CountWord(ReadString(), Chr(10))
  PAGE$(F) = StringField(ReadString(), F, Chr(10))
  Debug PAGE$(F)
Next F

; NBR DE LIGNE DU PROGRAMME
CHARMAX = CountWord(ReadString(), Chr(10))

; EXTRAIRE LES COMMANDES ET LEURS ATTRIBUTS
For L = 1 To CHARMAX
  For K = 1 To CountWord(PAGE$(CHAR), ";")
    
    CODE$(L, K) = StringField(PAGE$(L), k, ";")
    Debug CODE$(L, K)
    
  Next K
  
  CHAR = CHAR + 1
  
Next



; _________________________________________________________________________

; FONCTIONS
; _________________________________________________________________________

; FONCTIONS PROPRE A L'EXECUTEUR
Procedure.l CountWord(Chaine.s, Delimiteur.s)
  h = 1
  For t = 0 To Len(Chaine)
    k.s = Mid(Chaine, t, 1)
    If k = Delimiteur
      h + 1
    EndIf
  Next
  ProcedureReturn h
EndProcedure

; FONCTIONS DE L'UTILISATEUR
(c'est peut etre un peu bordelique mais bon je fait des tests)

J'ai utilisé ReadString() pour récuperer le contenu de mon fichier, avec une ligne ca va, mais deux c'est fichu (il retiens que la derniere !lol)

voilà le contenu de essai.txt:
print;salut
print;ca va?
Merci de m'aider
Oliv
Messages : 2117
Inscription : mer. 21/janv./2004 18:39

Message par Oliv »

Je ne suis pas trop habitué au maniment de fichiers mais à mon avis il faut revenir au début du fichier après chaque ReadString() avec la commande FileSeek(Position)
Aranoth
Messages : 293
Inscription : sam. 24/janv./2004 12:00
Localisation : Toulouse (31)
Contact :

Message par Aranoth »

J'ai fait quelques tests et...c'est bizarre (super conclusion :P )

En mettant une ligne vide avant le code, il accepte que la 1ere ligne

donc je déduis: il selectionne que la 2nd ligne (pk ? j'en sais rien)

J'ai essayé FileSeek():

Code : Tout sélectionner

; DECOUPER LES LIGNES
For F = 1 To CountWord(ReadString(), Chr(10))
  PAGE$(F) = StringField(ReadString(), F, Chr(10))
  Debug PAGE$(F)
  FileSeek(F)
Next F
Mais rien n'y fait ! :?
Avatar de l’utilisateur
cederavic
Messages : 1338
Inscription : lun. 09/févr./2004 23:38
Localisation : Bordeaux

Message par cederavic »

c'est simple en fait, un readstring passe a la ligne suivant et la lit vu que tu as mis 2 readstring, il lit la premiere pour le count word et il lit la deuxieme pour le stringfield
j'avais fait un ppti interpreteur de script moi aussi, voilas la base:

Code : Tout sélectionner

Declare.b OpenScript(ID.l, FileName.s)
Declare   CloseScript(ID.l)
Declare.b VerifScript(ID.l)
Declare.b ExecuteScript(ID.l)
Declare.b ExamineLine(Line.s)
Declare.b DoCommand(Command.s, Argument.s)
Declare   Command_MSG(Argument.s)

;[OpenScript]
;Ouvre un script FileName.s
;Valeur retournée :
;  0 = Impossible d'ouvrir le script FileName.s
;  1 = Script invalide
;  2 = Ouverture du script effectuée
;Note : l'ID sera aussi utiliser par OpenFile
Procedure.b OpenScript(ID.l, FileName.s)
  Result.b
  
  Result = OpenFile(ID, FileName)
  If Result = 0
    ProcedureReturn 0
  Else
    Result = VerifScript(ID)
  EndIf
  
  ProcedureReturn Result
EndProcedure

;[CloseScript]
;Ferme le script ID préalablement ouvert avec OpenScript
Procedure CloseScript(ID.l)
  CloseFile(ID)
EndProcedure

;[VerifScript]
;Verifi la validité du script ID en regardant s'il y a bien le nom de l'auteur et la version du script
;Valeur retournée :
;  1 = Script invalide
;  2 = Ouverture du script effectuée
Procedure.b VerifScript(ID.l)
  Result.b
  CurrentLine.s

  UseFile(ID)
  
  Repeat
    
    CurrentLine = ReadString()
    If Trim(UCase(StringField(CurrentLine, 1, "="))) = "AUTOR" : Result + 1 : EndIf
    If Trim(UCase(StringField(CurrentLine, 1, "="))) = "SCRIPTVERSION" : Result + 1 : EndIf
    
  Until Eof(ID) Or Result = 2
  FileSeek(0)
  
  ProcedureReturn Result
EndProcedure

;[ExecuteScript]
;Execute le script ID
;Valeur retournée :
;  0 = Script exécuté avec succes
;  1 = Commande inconnue
Procedure.b ExecuteScript(ID.l)
  Result.b
  CurrentLine.s
  
  UseFile(ID)
  
  Repeat
    
    CurrentLine = ReadString()
    Result = ExamineLine(CurrentLine)
    
  Until Eof(ID) Or Result > 0
EndProcedure

;[ExamineLine]
;Examine la ligne Line.s et effectu les commandes
;Valeur retournée :
;  0 = Ligne examinée et commande effectuée avec succes
;  1 = Commande inconnue
Procedure.b ExamineLine(Line.s)
  Command.s
  Argument.s
  
  Command = Trim(UCase(StringField(Line, 1, "=")))
  Argument = Trim(StringField(Line, 2, "="))
  
  ProcedureReturn DoCommand(Command, Argument)
EndProcedure

;[DoCommand]
;Execute la command Command.s avec l'argument Argument.s
;Valeur retournée :
;  0 = Commande exécutée avec succes
;  1 = Commande inconnue
Procedure.b DoCommand(Command.s, Argument.s)
  Result.b
  
  Select Command
    Case "MSG"
      Command_MSG(Argument)
      
    Case "AUTOR"
    
    Case "SCRIPTVERSION"
    
    Case ""
    
    Default
      Result = 1
  EndSelect
  
  ProcedureReturn Result
EndProcedure

;[Command_MSG]
;Exécute la commande MSG (MessageRequester)
;Syntax de la commande : MGS = Titre Message
Procedure Command_MSG(Argument.s)
  Title.s = Trim(StringField(Argument, 1, " "))
  MSG.s = Trim(StringField(Argument, 2, " "))
  
  MessageRequester(Title, MSG, 0)
EndProcedure
Avatar de l’utilisateur
cederavic
Messages : 1338
Inscription : lun. 09/févr./2004 23:38
Localisation : Bordeaux

Message par cederavic »

creer un fichier, ouvre le "script" avec OpenScript et execute le :)
il faut imperativement qu'il y ai Autor = **** et ScriptVersion = **** dans le fichier.
Il ne reconnait qu'une commande : MSG (la syntax est explikée) voilas, sa devrait t'aidé a debuté :)
Avatar de l’utilisateur
cederavic
Messages : 1338
Inscription : lun. 09/févr./2004 23:38
Localisation : Bordeaux

Message par cederavic »

Je vient de m'apercevoir que l'on peut metre juste un mot dan le message de MSG lol voila remplace par ça :

Code : Tout sélectionner

;[Command_MSG]
;Exécute la commande MSG (MessageRequester)
;Syntax de la commande : MGS = Titre Message
Procedure Command_MSG(Argument.s)
  Title.s = Trim(StringField(Argument, 1, " "))
  MSG.s = Trim(Mid(Argument, Len(Title) + 1, Len(Argument)))
  
  MessageRequester(Title, MSG, 0)
EndProcedure
Répondre