Taschenrechner Syntaxbaum erstellen

  • C#

Es gibt 1 Antwort in diesem Thema. Der letzte Beitrag () ist von RushDen.

    Taschenrechner Syntaxbaum erstellen

    Hi,

    Ich arbeite gerade daran einen Taschenrechner zu erstellen,
    dabei hab Ich jetzt Probleme den Syntaxbaum aufzubauen, also Ich hab die Lexikalische Analyse fertig implementiert, folgende Terminale sind gegeben:

    ADD,
    SUB,
    MUL,
    DIV,
    BROPEN,
    BRCLOSE,
    INTNUM,
    DECNUM,
    ID,

    Die Regeln hab ich erstmal nur die grundrechenarten ohne Klammern und bezeichner.

    START -> NUMBER TERM
    OPERATOR -> add | sub | mul | div
    NUMBER -> decnum | intnum
    TERM -> OPERATOR START | EMPTY

    Jetzt weiß Ich nicht wie Ich vorgehen soll, um die vorliegenden Token in so eine Baum-Struktur zu kriegen, ich hab 3 Klassen modelliert:

    C#-Quellcode

    1. public class SyntaxTree<T>
    2. {
    3. public SyntaxTree(T pValue, params SyntaxTree<T>[] pNode)
    4. {
    5. this.Value = pValue;
    6. this.Nodes = pNode.ToList();
    7. }
    8. public SyntaxTree(T pValue)
    9. {
    10. this.Value = pValue;
    11. this.Nodes = new List<SyntaxTree<T>>();
    12. }
    13. public T Value { get; private set; }
    14. public List<SyntaxTree<T>> Nodes { get; set; }
    15. }


    und

    C#-Quellcode

    1. public class Grammar
    2. {
    3. public Grammar(string pLeft, params MultipleValue[] pValues)
    4. {
    5. LeftValue = pLeft;
    6. RightValue = pValues;
    7. }
    8. public string LeftValue { get; private set; }
    9. public MultipleValue[] RightValue { get; private set; }
    10. public bool Contains(string pValue, ref MultipleValue pVal, int pIndex)
    11. {
    12. foreach (var item in RightValue)
    13. {
    14. foreach (var elem in item.Values)
    15. {
    16. if (elem == pValue)
    17. {
    18. pVal = item;
    19. if (pIndex == 0)
    20. return true;
    21. pIndex--;
    22. }
    23. }
    24. }
    25. return false;
    26. }
    27. }
    28. public class MultipleValue
    29. {
    30. public MultipleValue(params string[] pValues)
    31. {
    32. this.Values = pValues;
    33. }
    34. public string[] Values { get; private set; }
    35. }


    Habe schon einiges ausprobiert gehabt, das meiste was mir Probleme bereit hat, war die Überprüfung welche der Definitionen nun genommen werden soll damit kein Stackoverflow entsteht (also rekursiv hab Ich den Baum befüllt), wie bei TERM und START, weil das ja mit der Eingabe zusammenhängt und den Algorithmus dafür krieg Ich nicht so recht hin, wäre gut wenn mir jemand helfen könnte.
    Der betreffende Teil ist in Form1.cs im Konstruktur

    Die Projektmappe ist im Anhang.
    Dateien
    • MathParser.zip

      (76,04 kB, 50 mal heruntergeladen, zuletzt: )
    So habs endlich geschafft. Zumindest funktioniert dieser Algo bis jetzt (wen's interessiert):

    C#-Quellcode

    1. private IEnumerable<SyntaxTree<string>> FillRecursive(string pElement, List<Token> allTokens)
    2. {
    3. foreach (var elem in _grammars)
    4. {
    5. if (elem.LeftValue == pElement)
    6. {
    7. MultipleValue lFirst = elem.RightValue[0];
    8. Token lSmallestToken = null;
    9. foreach (var element in elem.RightValue)
    10. {
    11. foreach (var ie in allTokens)
    12. {
    13. if (element.Values.Any((iste) => iste == ie.ToString()))
    14. {
    15. if (lSmallestToken == null || allTokens.IndexOf(lSmallestToken) > allTokens.IndexOf(ie))
    16. {
    17. lSmallestToken = ie;
    18. lFirst = element;
    19. }
    20. }
    21. }
    22. }
    23. if (lSmallestToken != null)
    24. {
    25. allTokens.Remove(lSmallestToken);
    26. foreach (var item in lFirst.Values)
    27. {
    28. SyntaxTree<string> lTree = new SyntaxTree<string>(item, FillRecursive(item, allTokens).ToArray());
    29. yield return lTree;
    30. }
    31. break;
    32. }
    33. else if (allTokens.Count == 0)
    34. yield break;
    35. foreach (var item in lFirst.Values)
    36. {
    37. SyntaxTree<string> lTree = new SyntaxTree<string>(item, FillRecursive(item, allTokens).ToArray());
    38. yield return lTree;
    39. }
    40. }
    41. }
    42. }