Seite 1 von 1

Scanner für einen Compiler

Verfasst: 14.06.2007 22:46
von coMstructor
Hi,
habe mal meinen Scanner ein bisschen kommentiert, hoffe es interessiert wen, ist aber nicht so anspruchsvoll, von daher leicht zu kapieren.

Code: Alles auswählen

; Prozeduren, die für uns wichtig werden

Procedure.b IsNumeric(Expression.s)
  If FindString("0123456789",expression,1) 
      ProcedureReturn 1
  Else 
      ProcedureReturn 0
  EndIf 
EndProcedure 

 
Procedure.f IsOperator(Expression.s) 
    If Expression = "+" Or Expression = "-" Or Expression = "*" Or Expression = "/" Or Expression = "=" Or Expression = "&"
        ProcedureReturn 1
    Else 
        ProcedureReturn 0
    EndIf 
EndProcedure 

; Scanner (Hauptquellcode)

Global NewList symb.s() 

file$=OpenFileRequester("Bitte Datei zum Laden auswählen", "","Text (*.txt)|*.txt|Alle Dateien (*.*)|*.*" , 0)
If file$
OpenFile(0,file$)

    Repeat   
        
        Line.s=ReadString(0)                      ; Hier wird Zeile für Zeile eingelesen
    
        For i = 1 To Len(Line)                     ; Hier wird Zeichen für Zeichen bearbeitet
     
        ThisChar.s = Mid(Line, i, 1)              
        
     
        If IsOperator(ThisChar)=1               ; Falls Zeichen ein Operator ist 
         
            If WasOperator = 1  
                MessageRequester("Syntaxfehler","Fehler: Unerwarteter Operator.")                             
            Else 
                AddElement(Symb()):Symb() = ThisChar 
                WasOperator = 1 
            EndIf 
         
        ElseIf ThisChar = "(" Or ThisChar = ")"   ; Falls Zeichen eine Klammer ist
                  AddElement(symb()):Symb() = ThisChar
                  WasOperator = 0 
                     
        ElseIf ThisChar = Chr(34)         ; Falls Zeichen ein Anführungszeichen ist

            AddElement(symb()):Symb() = Chr(34)
         
            For j = (i + 1) To Len(Line) 
         
                ThisChar = Mid(Line, j, 1) 
                 
                If ThisChar = Chr(34)  
                    Symb() = Symb()+ ThisChar
                    i = j: Break  
                Else 
                    Symb() = Symb()+ ThisChar
                EndIf 
             
            Next j
             
        WasOperator = 0 
         
        ElseIf IsNumeric(ThisChar)   ; Falls Zeichen eine Zahl ist
         
            AddElement(symb()):Symb() = "" 
            
            For j = i To Len(Line)       ; Verhalten für die folgenden Zeichen nach der Zahl
             
                ThisChar = Mid(Line, j, 1) 
                 
                If IsNumeric(ThisChar)  
                    Symb() = Symb() + ThisChar 

                ElseIf ThisChar = " " 
                
                    i = j: Goto Skip 
                    
                ElseIf IsOperator(ThisChar) Or ThisChar = ")" Or ThisChar = "(" 
                    
                    i = (j - 1): Goto Skip 
                Else 
                    
                    MessageRequester("Syntaxfehler","Fehler: Unerwartetes Zeichen.")     
                      
                EndIf 
             
            Next j 
             
            SymbNo = SymbNo + 1 
            
            WasOperator = 0 
             
        ElseIf ThisChar = " "   ; Leerzeichen überspringen

        Else                         ; Falls Zeichen ein Buchstabe ist
            AddElement(symb()):Symb() = "" 
         
            For j = i To Len(Line) 
             
                ThisChar = Mid(Line, j, 1) 
                 
                If IsOperator(ThisChar) Or ThisChar = ")" Or ThisChar = "(" 
                    SymbNo = SymbNo + 1: i = (j - 1): Goto Skip 
                    
                ElseIf ThisChar = " "  
                    SymbNo = SymbNo + 1: i = j: Goto Skip 
                    
                Else 
                    Symb() = Symb() + LCase(ThisChar) 

                EndIf 
             
            Next j 
             
            i = j 
             
Skip: 
         
            WasOperator = 0 
 
        EndIf 
        
        
    Next i 
    
        
    Until Eof(0)
    CloseFile(0) 
    
  Else
    MessageRequester("Info","Datei nicht gefunden/konnte nicht geöffnet werden!")
  EndIf

; Dieser Abschnitt nur zur Anzeige von den Token wichtig

ForEach symb()
	Debug symb()
Next
Um den Code zu testen empfehle ich euch ne datei anzulegen mit dem Inhalt

Code: Alles auswählen

33+asdfdsaf-(hallo)*"Welt"/kaiser.s
In dieser Zeile sollte schon aufgezeigt werden wie der Scanner die Zeichen einteilt.