Hi,
ich habe vor langer Zeit mal an einem Parser rumgebaut und das Projekt nun wieder herausgekramt. So weit hab ich ihn nun:
Spoiler anzeigen
Das funktioniert soweit auch gut - bis eben mehrere Klammern ins Spiel kommen. Hier mal das Grundgerüst:
Spoiler anzeigen
NewSplit befüllt die Tokenlist mit den einzelnen Zahlen, Operatoren. SolveMinusProblem schiebt zum Beispiel bei 12*-1 das Minus und die 1 in ein Token. Durch die NewSplit-Function entstehen Leerzeichen die durch die Function DeleteEmpty gelöscht werden.
Soviel zu dem aktuellen Stand. Wie kann ich nun weitermachen ohne allzuviel an der bisherigen Grundstruktur herumzufummeln ? Danke für eure Hilfe
ich habe vor langer Zeit mal an einem Parser rumgebaut und das Projekt nun wieder herausgekramt. So weit hab ich ihn nun:
Visual Basic-Quellcode
- Public Class Parser
- Public Token_List As New List(Of String)
- Private Function NewSplit(ByVal sen As String, ByVal splitter As Char()) As List(Of String)
- Dim final_list As New List(Of String)
- Dim last_found As Integer = 0
- For u = 0 To sen.Length - 1
- For Each Chr As Char In splitter
- If Char.Parse(sen(u)) = Chr Then
- final_list.Add(sen.Substring(last_found, u - last_found))
- final_list.Add(sen(u))
- last_found = u + 1
- End If
- Next
- Next
- If last_found < sen.Length Then
- final_list.Add(sen.Substring(last_found, sen.Length - last_found))
- End If
- Return final_list
- End Function
- Private Function SolveMinusProblem(ByVal liste As List(Of String)) As List(Of String)
- If liste(0) = "-" AndAlso IsNumeric(liste(1)) Then
- liste(1) = "-" + liste(1)
- liste.RemoveAt(0)
- End If
- For i As Integer = 1 To liste.Count - 1
- If i < liste.Count AndAlso i - 1 < liste.Count Then
- If liste(i) = "-" AndAlso IsNumeric(liste(i - 1)) = False Then
- liste(i + 1) = "-" + liste(i + 1)
- liste.RemoveAt(i)
- liste.Remove("")
- End If
- End If
- Next
- Return liste
- End Function
- Public Function Eval(ByVal expression As String) As Double
- Token_List = SolveMinusProblem(NewSplit(expression, {"^"c, "/"c, "*"c, "+"c, "-"c, "("c, ")"c}))
- Token_List = DeleteEmpty(Token_List)
- While Token_List.Count > 1
- While Contains(Token_List, "^", True)
- Dim opindex As Integer = GetIndex(Token_List, "^")
- Token_List(opindex) = Math.Pow(Double.Parse(Token_List(opindex - 1)), Double.Parse(Token_List(opindex + 1))).ToString
- Token_List.RemoveAt(opindex - 1)
- Token_List.RemoveAt(opindex)
- Token_List = DeletEmptyBrackets(Token_List)
- End While
- While Contains(Token_List, "/", True)
- Dim opindex As Integer = GetIndex(Token_List, "/")
- Token_List(opindex) = (Double.Parse(Token_List(opindex - 1)) / Double.Parse(Token_List(opindex + 1))).ToString
- Token_List.RemoveAt(opindex - 1)
- Token_List.RemoveAt(opindex)
- Token_List = DeletEmptyBrackets(Token_List)
- End While
- While Contains(Token_List, "*", True)
- Dim opindex As Integer = GetIndex(Token_List, "*")
- Token_List(opindex) = (Double.Parse(Token_List(opindex - 1)) * Double.Parse(Token_List(opindex + 1))).ToString
- Token_List.RemoveAt(opindex - 1)
- Token_List.RemoveAt(opindex)
- Token_List = DeletEmptyBrackets(Token_List)
- End While
- While Contains(Token_List, "-", True)
- Dim opindex As Integer = GetIndex(Token_List, "-")
- Token_List(opindex) = (Double.Parse(Token_List(opindex - 1)) - Double.Parse(Token_List(opindex + 1))).ToString
- Token_List.RemoveAt(opindex - 1)
- Token_List.RemoveAt(opindex)
- Token_List = DeletEmptyBrackets(Token_List)
- End While
- While Contains(Token_List, "+", True)
- Dim opindex As Integer = GetIndex(Token_List, "+")
- Token_List(opindex) = (Double.Parse(Token_List(opindex - 1)) + Double.Parse(Token_List(opindex + 1))).ToString
- Token_List.RemoveAt(opindex - 1)
- Token_List.RemoveAt(opindex)
- Token_List = DeletEmptyBrackets(Token_List)
- End While
- End While
- Return Double.Parse(Token_List.ElementAt(0))
- End Function
- Private Function Contains(ByVal liste As List(Of String), ByVal search As String, ByVal isoperator As Boolean) As Boolean
- Dim re = False
- For u = 0 To liste.Count - 1
- If liste(u) = search AndAlso isoperator AndAlso IsNumeric(liste(u - 1)) AndAlso IsNumeric(liste(u + 1)) Then re = True
- If liste(u) = search AndAlso isoperator = False AndAlso IsNumeric(liste(u + 1)) AndAlso liste(u + 2) = ")" Then re = True
- Next
- Return re
- End Function
- Private Function GetIndex(ByVal liste As List(Of String), ByVal search As String) As Integer
- For u = 0 To liste.Count - 1
- If search = liste(u) Then Return u
- Next
- End Function
- Private Function DeletEmptyBrackets(ByVal liste As List(Of String)) As List(Of String)
- While Contains(liste, "(", False)
- Dim brackopen As Integer = GetIndex(liste, "(")
- If IsNumeric(liste(brackopen + 1)) AndAlso liste(brackopen + 2) = ")" Then
- liste.RemoveAt(brackopen)
- liste.RemoveAt(brackopen + 1)
- End If
- End While
- Return liste
- End Function
- Private Function DeleteEmpty(ByVal liste As List(Of String)) As List(Of String)
- While liste.Contains("")
- liste.Remove("")
- End While
- Return liste
- End Function
- End Class
Das funktioniert soweit auch gut - bis eben mehrere Klammern ins Spiel kommen. Hier mal das Grundgerüst:
VB.NET-Quellcode
- Public Class Parser
- Public Token_List As New List(Of String)
- Private Function NewSplit(ByVal sen As String, ByVal splitter As Char()) As List(Of String)
- Dim final_list As New List(Of String)
- Dim last_found As Integer = 0
- For u = 0 To sen.Length - 1
- For Each Chr As Char In splitter
- If Char.Parse(sen(u)) = Chr Then
- final_list.Add(sen.Substring(last_found, u - last_found))
- final_list.Add(sen(u))
- last_found = u + 1
- End If
- Next
- Next
- If last_found < sen.Length Then
- final_list.Add(sen.Substring(last_found, sen.Length - last_found))
- End If
- Return final_list
- End Function
- Private Function SolveMinusProblem(ByVal liste As List(Of String)) As List(Of String)
- If liste(0) = "-" AndAlso IsNumeric(liste(1)) Then
- liste(1) = "-" + liste(1)
- liste.RemoveAt(0)
- End If
- For i As Integer = 1 To liste.Count - 1
- If i < liste.Count AndAlso i - 1 < liste.Count Then
- If liste(i) = "-" AndAlso IsNumeric(liste(i - 1)) = False Then
- liste(i + 1) = "-" + liste(i + 1)
- liste.RemoveAt(i)
- liste.Remove("")
- End If
- End If
- Next
- Return liste
- End Function
- Public Function Eval(ByVal expression As String) As Double
- Token_List = SolveMinusProblem(NewSplit(expression, {"^"c, "/"c, "*"c, "+"c, "-"c, "("c, ")"c}))
- Token_List = DeleteEmpty(Token_List)
- End Function
- Private Function Contains(ByVal liste As List(Of String), ByVal search As String, ByVal isoperator As Boolean) As Boolean
- Dim re = False
- For u = 0 To liste.Count - 1
- If liste(u) = search AndAlso isoperator AndAlso IsNumeric(liste(u - 1)) AndAlso IsNumeric(liste(u + 1)) Then re = True
- If liste(u) = search AndAlso isoperator = False AndAlso IsNumeric(liste(u + 1)) AndAlso liste(u + 2) = ")" Then re = True
- Next
- Return re
- End Function
- Private Function GetIndex(ByVal liste As List(Of String), ByVal search As String) As Integer
- For u = 0 To liste.Count - 1
- If search = liste(u) Then Return u
- Next
- End Function
- Private Function DeletEmptyBrackets(ByVal liste As List(Of String)) As List(Of String)
- While Contains(liste, "(", False)
- Dim brackopen As Integer = GetIndex(liste, "(")
- If IsNumeric(liste(brackopen + 1)) AndAlso liste(brackopen + 2) = ")" Then
- liste.RemoveAt(brackopen)
- liste.RemoveAt(brackopen + 1)
- End If
- End While
- Return liste
- End Function
- Private Function DeleteEmpty(ByVal liste As List(Of String)) As List(Of String)
- While liste.Contains("")
- liste.Remove("")
- End While
- Return liste
- End Function
- End Class
NewSplit befüllt die Tokenlist mit den einzelnen Zahlen, Operatoren. SolveMinusProblem schiebt zum Beispiel bei 12*-1 das Minus und die 1 in ein Token. Durch die NewSplit-Function entstehen Leerzeichen die durch die Function DeleteEmpty gelöscht werden.
Soviel zu dem aktuellen Stand. Wie kann ich nun weitermachen ohne allzuviel an der bisherigen Grundstruktur herumzufummeln ? Danke für eure Hilfe


