Scanner für einen Compiler
Verfasst: 14.06.2007 22:46
Hi,
habe mal meinen Scanner ein bisschen kommentiert, hoffe es interessiert wen, ist aber nicht so anspruchsvoll, von daher leicht zu kapieren.
Um den Code zu testen empfehle ich euch ne datei anzulegen mit dem Inhalt
In dieser Zeile sollte schon aufgezeigt werden wie der Scanner die Zeichen einteilt.
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
Code: Alles auswählen
33+asdfdsaf-(hallo)*"Welt"/kaiser.s