tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
4
ZUGRIFFE
190
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
  1. #1
    Avatar von Spyke
    Spyke Spyke ist offline Capoeirista
    Registriert seit
    Oct 2002
    Beiträge
    931
    Zum testen am besten den letzten Dateianhang dieses Thread verwenden.

    Die erste Version des Interpreters läuft mit Hilfe von Regular Expression

    Der Interpreter
    Code csharp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    
        internal class BFInterpreter
        {
            /// <summary>
            /// wird aufgerufen wenn eine Eingabe erwartet wird
            /// </summary>
            /// <returns>ASCII Wert des eingegebenen Zeichens</returns>
            public delegate int Input();
            /// <summary>
            /// wird aufgerufen wenn eine Ausgabe erwartet wird
            /// </summary>
            /// <param name="value">ASCII Wert des auszugebenen Zeichens</param>
            public delegate void Output(int value);
     
            /// <summary>
            /// Objekt wird erstellt
            /// </summary>
            /// <param name="input">Methode für Eingabe</param>
            /// <param name="output">Methode für Ausgabe</param>
            internal BFInterpreter(Input input, Output output)
            {
                this.input = input;
                this.output = output;
            }
     
            /// <summary>
            /// Interpreter wird gestartet
            /// </summary>
            /// <param name="s">Zeichenkette die untersucht werden soll</param>
            public void Parse(string s)
            {
                Dictionary<int, int> band = new Dictionary<int, int>();
                int position = 0;
     
                band.Add(position, 0);
     
                Parse(band, ref position, s);
            }
     
            /// <summary>
            /// analysiert die Zeichenkette
            /// </summary>
            /// <param name="band">Speicher</param>
            /// <param name="position">Position im Speicher</param>
            /// <param name="s">zu untersuchende Zeichenkette</param>
            private void Parse(Dictionary<int, int> band, ref int position, string s)
            {
                //Zeichen '+'
                string pInkr = @"(?'inkr'\+{1,})";
                //Zeichen '-'
                string pDekr = @"(?'dekr'-{1,})";
                //Zeichen '>'
                string pPointInkr = @"(?'PointInkr'>{1,})";
                //Zeichen '<'
                string pPointDekr = @"(?'PointDekr'<{1,})";
                //Zeichen '.' (Ausgabe)
                string pOutput = @"(?'output'\.)";
                //Zeichen ',' (Eingabe)
                string pInput = @"(?'input',)";
                //Zeichen '[' (Blockbeginn)
                string pBlockBeginn = @"(?'blockbeginn'\[.*)";
     
                //Hilfspattern für die übrigen Zeichen
                string pCheck = @"[^\+\-\[\]\<\>\.\,]*";
     
                //Zeichenkette untersuchen
                foreach (Match m in Regex.Matches(s, pInkr + "|" + pDekr + "|" + pPointInkr + "|" + pPointDekr + "|" + pOutput + "|" + pInput + "|" + pBlockBeginn + "|" + pCheck, RegexOptions.Singleline))
                {
                    if (m.Groups["inkr"].Success) //Zeichen '+'
                    {
                        band[position] += m.Groups["inkr"].Value.Length;
                        if (band[position] > 255)
                            band[position] = 0;
                    }
                    else if (m.Groups["dekr"].Success) //Zeichen '-'
                    {
                        band[position] -= m.Groups["dekr"].Value.Length;
                        if (band[position] < 0)
                            band[position] = 255;
                    }
                    else if (m.Groups["PointInkr"].Success) //Zeichen '>'
                    {
                        position += m.Groups["PointInkr"].Value.Length;
                        if (!band.ContainsKey(position))
                            band.Add(position, 0);
                    }
                    else if (m.Groups["PointDekr"].Success) //Zeichen '<'
                    {
                        position -= m.Groups["PointDekr"].Value.Length;
                        if (!band.ContainsKey(position))
                            band.Add(position, 0);
                    }
                    else if (m.Groups["output"].Success) //Zeichen '.' (Ausgabe)
                        output(band[position]);
                    else if (m.Groups["input"].Success) //Zeichen ',' (Eingabe)
                        band[position] = input();
                    else if (m.Groups["blockbeginn"].Success)
                    {
                        string block = m.Groups["blockbeginn"].Value.Substring(1);
                        int endBlock = EndBlock(block);
                        if (endBlock > -1)
                        {
                            string block2 = block.Substring(0, endBlock);
                            while (band[position] != 0)
                                Parse(band, ref position, block2);
                        }
     
                        if (endBlock < block.Length) //ist noch nicht das Ende, weiter parsen
                            Parse(band, ref position, block.Substring(endBlock));
                    }
                }
            }
     
            /// <summary>
            /// sucht Ende des aktuellen Blockes
            /// </summary>
            private int EndBlock(string block)
            {
                int beginnCounter = 0; //Prüf Variable für innere Blöcke
                for (int i = 0; i < block.Length; i++)
                {
                    if (block[i] == '[')
                        beginnCounter++;
                    else if (block[i] == ']')
                    {
                        if (beginnCounter == 0)
                            return i;
                        beginnCounter--;
                    }
                }
                return -1;
            }
     
            private readonly Input input;
            private readonly Output output;
        }

    Aufruf:
    Code csharp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    
    class Program
        {
            static void Main(string[] args)
            {
                if (args.GetLength(0) > 0)
                {
                    if (File.Exists(args[0]))
                    {
                        string s = File.ReadAllText(args[0]);
     
                        Console.WriteLine("Regex Version");
                        Console.WriteLine(string.Empty);
     
                        BF.Net.BFInterpreter bfi = new BF.Net.BFInterpreter(Input, Output);
                        bfi.Parse(s);
     
                        Console.WriteLine(string.Empty);
                        Console.WriteLine(string.Empty);
                        Console.WriteLine("Drücken Sie eine Taste zum Beenden des Programmes ...");
                        Console.ReadKey();
                    }
                }
            }
     
            /// <summary>
            /// wird aufgerufen wenn eine Eingabe erwartet wird
            /// </summary>
            public static int Input()
            {
                return (int)Console.ReadKey(false).KeyChar;
            }
     
            /// <summary>
            /// wird aufgerufen wenn eine Ausgabe erwartet wird
            /// </summary>
            public static void Output(int value)
            {
                Console.Write((char)value);
            }
        }
    Angehängte Dateien Angehängte Dateien
    Geändert von Spyke (03.10.08 um 18:24 Uhr)
     
    www.iv-interactive.de - Projektewebsite
    WikiParser - aktuelles Projekt

  2. #2
    Avatar von Spyke
    Spyke Spyke ist offline Capoeirista
    Registriert seit
    Oct 2002
    Beiträge
    931
    Die zweite Version des Interpreters durchläuft die Zeichenkette in einer Schleife und prüft jedes Zeichen

    Der Interpreter
    Code csharp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    
        internal class BFInterpreter
        {
            /// <summary>
            /// wird aufgerufen wenn eine Eingabe erwartet wird
            /// </summary>
            /// <returns>ASCII Wert des eingegebenen Zeichens</returns>
            public delegate int Input();
            /// <summary>
            /// wird aufgerufen wenn eine Ausgabe erwartet wird
            /// </summary>
            /// <param name="value">ASCII Wert des auszugebenen Zeichens</param>
            public delegate void Output(int value);
     
            /// <summary>
            /// Objekt wird erstellt
            /// </summary>
            /// <param name="input">Methode für Eingabe</param>
            /// <param name="output">Methode für Ausgabe</param>
            internal BFInterpreter(Input input, Output output)
            {
                this.input = input;
                this.output = output;
            }
     
            /// <summary>
            /// Interpreter wird gestartet
            /// </summary>
            /// <param name="s">Zeichenkette die untersucht werden soll</param>
            public void Parse2(string s)
            {
                Dictionary<int, int> band = new Dictionary<int, int>();
                int position = 0;
     
                band.Add(position, 0);
     
                Parse2(band, ref position, s);
            }
     
            /// <summary>
            /// analysiert die Zeichenkette
            /// </summary>
            /// <param name="band">Speicher</param>
            /// <param name="position">Position im Speicher</param>
            /// <param name="s">zu untersuchende Zeichenkette</param>
            private void Parse2(Dictionary<int, int> band, ref int position, string s)
            {
                for (int i = 0; i < s.Length; i++)
                {
                    switch (s[i])
                    {
                        case '+':
                            {
                                band[position]++;
                                if (band[position] > 255)
                                    band[position] = 0;
                            } break;
                        case '-':
                            {
                                band[position]--;
                                if (band[position] < 0)
                                    band[position] = 255;
                            } break;
                        case '>':
                            {
                                position++;
                                if (!band.ContainsKey(position))
                                    band.Add(position, 0);
                            } break;
                        case '<':
                            {
                                position--;
                                if (!band.ContainsKey(position))
                                    band.Add(position, 0);
                            } break;
                        case '.':
                            {
                                output(band[position]);
                            } break;
                        case ',':
                            {
                                band[position] = input();
                            } break;
                        case '[':
                            {
                                string block = s.Substring(i + 1);
                                int endBlock = EndBlock(block);
                                if (endBlock > -1)
                                {
                                    string block2 = block.Substring(0, endBlock);
                                    while (band[position] != 0)
                                        Parse2(band, ref position, block2);
                                }
     
                                if (endBlock < block.Length) //ist noch nicht das Ende, weiter parsen
                                    Parse2(band, ref position, block.Substring(endBlock));
     
                                s = string.Empty; //Schleife abbrechen
                            } break;
                        default:
                            break;
                    }
                }
            }
     
            /// <summary>
            /// sucht Ende des aktuellen Blockes
            /// </summary>
            private int EndBlock(string block)
            {
                int beginnCounter = 0; //Prüf Variable für innere Blöcke
                for (int i = 0; i < block.Length; i++)
                {
                    if (block[i] == '[')
                        beginnCounter++;
                    else if (block[i] == ']')
                    {
                        if (beginnCounter == 0)
                            return i;
                        beginnCounter--;
                    }
                }
                return -1;
            }
     
            private readonly Input input;
            private readonly Output output;
        }

    Aufruf:
    Code csharp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    
    class Program
        {
            static void Main(string[] args)
            {
                if (args.GetLength(0) > 0)
                {
                    if (File.Exists(args[0]))
                    {
                        string s = File.ReadAllText(args[0]);
     
                        Console.WriteLine("Schleifen Version");
                        Console.WriteLine(string.Empty);
     
                        BF.Net.BFInterpreter bfi = new BF.Net.BFInterpreter(Input, Output);
                        bfi.Parse2(s);
     
                        Console.WriteLine(string.Empty);
                        Console.WriteLine(string.Empty);
                        Console.WriteLine("Drücken Sie eine Taste zum Beenden des Programmes ...");
                        Console.ReadKey();
                    }
                }
            }
     
            /// <summary>
            /// wird aufgerufen wenn eine Eingabe erwartet wird
            /// </summary>
            public static int Input()
            {
                return (int)Console.ReadKey(false).KeyChar;
            }
     
            /// <summary>
            /// wird aufgerufen wenn eine Ausgabe erwartet wird
            /// </summary>
            public static void Output(int value)
            {
                Console.Write((char)value);
            }
        }
    Angehängte Dateien Angehängte Dateien
    Geändert von Spyke (03.10.08 um 15:56 Uhr)
     
    www.iv-interactive.de - Projektewebsite
    WikiParser - aktuelles Projekt

  3. #3
    Avatar von Spyke
    Spyke Spyke ist offline Capoeirista
    Registriert seit
    Oct 2002
    Beiträge
    931
    Die angehängten Zip Dateien öffnen und die BFEditor.exe starten.
    In dem Textfeld kann dann rumprobiert werden.
     
    www.iv-interactive.de - Projektewebsite
    WikiParser - aktuelles Projekt

  4. #4
    Avatar von Spyke
    Spyke Spyke ist offline Capoeirista
    Registriert seit
    Oct 2002
    Beiträge
    931
    Hier nochmals 2 neue Versionen für Regex und Schleife.

    Für direkte Text Eingabe wieder BFEditor.exe verwenden oder der BFConsole.exe einen Dateipfad übergeben.

    P.S.: Schleifen Version ist schneller
    Angehängte Dateien Angehängte Dateien
     
    www.iv-interactive.de - Projektewebsite
    WikiParser - aktuelles Projekt

  5. #5
    Avatar von Spyke
    Spyke Spyke ist offline Capoeirista
    Registriert seit
    Oct 2002
    Beiträge
    931
    Und eine andere Variante
    jetzt kann man endlich auch das Textadventure spielen.


    Interpreter:
    Code csharp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    
    internal class BFInterpreter
        {
            /// <summary>
            /// wird aufgerufen wenn eine Eingabe erwartet wird
            /// </summary>
            /// <returns>ASCII Wert des eingegebenen Zeichens</returns>
            public delegate int Input();
            /// <summary>
            /// wird aufgerufen wenn eine Ausgabe erwartet wird
            /// </summary>
            /// <param name="value">ASCII Wert des auszugebenen Zeichens</param>
            public delegate void Output(int value);
     
            /// <summary>
            /// Objekt wird erstellt
            /// </summary>
            /// <param name="input">Methode für Eingabe</param>
            /// <param name="output">Methode für Ausgabe</param>
            internal BFInterpreter(Token token, Input input, Output output)
            {
                this.token = token;
                this.input = input;
                this.output = output;
            }
     
            public void Start()
            {
                Dictionary<int, int> band = new Dictionary<int, int>();
                band.Add(0, 0);
     
                int position = 0;
     
                Analize(token, band, ref position);
            }
     
            /// <summary>
            /// Analysiert die Token und führt entsprechende Aktionen aus
            /// </summary>
            /// <param name="token">Liste der Token</param>
            /// <param name="band">Speicher</param>
            /// <param name="position">Zeiger</param>
            private void Analize(Token token, Dictionary<int, int> band, ref int position)
            {
                foreach (Token tok in token)
                {
                    switch (tok.Typ)
                    {
                        case TokenTyp.PointerLeft:
                            {
                                position--;
                                if (!band.ContainsKey(position))
                                    band.Add(position, 0);
                            } break;
                        case TokenTyp.PointerRight:
                            {
                                position++;
                                if (!band.ContainsKey(position))
                                    band.Add(position, 0);
                            } break;
                        case TokenTyp.Increment:
                            {
                                band[position]++;
                                if (band[position] > 255)
                                    band[position] = 0;
                            } break;
                        case TokenTyp.Decrement:
                            {
                                band[position]--;
                                if (band[position] < 0)
                                    band[position] = 255;
                            } break;
                        case TokenTyp.Input:
                            {
                                band[position] = input();
                            } break;
                        case TokenTyp.Output:
                            {
                                output(band[position]);
                            } break;
                        case TokenTyp.Block:
                            {
                                while (band[position] != 0)
                                    Analize(tok, band, ref position);
                            } break;
                    }
                }
            }
     
            /// <summary>
            /// analysiert die Zeichenkette
            /// </summary>
            /// <param name="s">zu untersuchende Zeichenkette</param>
            public static Token Parse(string s)
            {
                Dictionary<int, Token> tokenBlock = new Dictionary<int, Token>(); //Hilfs Dictionary zum halten der Blockebene
                int blockCounter = 0; //aktuelle Blockebene
     
                tokenBlock.Add(blockCounter, new Token());
     
                for (int i = 0; i < s.Length; i++)
                {
                    switch (s[i])
                    {
                        case '+': tokenBlock[blockCounter].Add(new Token(TokenTyp.Increment)); break;
                        case '-': tokenBlock[blockCounter].Add(new Token(TokenTyp.Decrement)); break;
                        case '>': tokenBlock[blockCounter].Add(new Token(TokenTyp.PointerRight)); break;
                        case '<': tokenBlock[blockCounter].Add(new Token(TokenTyp.PointerLeft)); break;
                        case '.': tokenBlock[blockCounter].Add(new Token(TokenTyp.Output)); break;
                        case ',': tokenBlock[blockCounter].Add(new Token(TokenTyp.Input)); break;
                        case '[':
                            {
                                Token tokBlock = new Token();
     
                                tokenBlock[blockCounter].Add(tokBlock);
                                tokenBlock.Add(blockCounter + 1, tokBlock);
     
                                blockCounter++;
                            } break;
                        case ']':
                            {
                                tokenBlock.Remove(blockCounter);
                                blockCounter--;
                            } break;
                        default:
                            break;
                    }
                }
     
                return tokenBlock[0];
            }
     
            private readonly Token token;
            private readonly Input input;
            private readonly Output output;
        }
    Code csharp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    internal class BFInterpreter
        {
            /// <summary>
            /// Tokentypen
            /// </summary>
            public enum TokenTyp
            {
                PointerLeft = 1,
                PointerRight = 2,
                Increment = 3,
                Decrement = 4,
                Input = 5,
                Output = 6,
                Block = 7
            }
        }
    Code csharp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    
    internal class BFInterpreter
        {
            /// <summary>
            /// Klasse zum halten der Token (für Blöcke zum halten ihrer Token)
            /// </summary>
            public class Token : IEnumerable<Token>
            {
                internal Token()
                    : this(TokenTyp.Block)
                {
                }
     
                internal Token(TokenTyp typ)
                {
                    this.typ = typ;
                    this.token = new List<Token>();
                }
     
                /// <summary>
                /// Typ
                /// </summary>
                public TokenTyp Typ
                {
                    get { return typ; }
                }
     
                internal void Add(Token tok)
                {
                    token.Add(tok);
                }
     
                #region IEnumerable<Token> Members
     
                public IEnumerator<Token> GetEnumerator()
                {
                    return token.GetEnumerator();
                }
     
                #endregion
     
                #region IEnumerable Members
     
                System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
                {
                    return token.GetEnumerator();
                }
     
                #endregion
     
                private readonly TokenTyp typ;
                private readonly List<Token> token;
            }
        }

    Aufruf:
    Code csharp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    
        class Program
        {
            static void Main(string[] args)
            {
                if (args.GetLength(0) > 0)
                {
                    if (File.Exists(args[0]))
                    {
                        string s = File.ReadAllText(args[0]);
     
                        BF.Net.BFInterpreter.Token token = BF.Net.BFInterpreter.Parse(s);
     
                        BF.Net.BFInterpreter bfi = new BF.Net.BFInterpreter(token, Input, Output);
                        bfi.Start();
     
                        Console.WriteLine(string.Empty);
                        Console.WriteLine(string.Empty);
                        Console.WriteLine("Drücken Sie eine Taste zum Beenden des Programmes ...");
                        Console.ReadKey();
                    }
                }
            }
     
            /// <summary>
            /// wird aufgerufen wenn eine Eingabe erwartet wird
            /// </summary>
            public static int Input()
            {
                Char chr = Console.ReadKey().KeyChar;
                return (int)chr;
            }
     
            /// <summary>
            /// wird aufgerufen wenn eine Ausgabe erwartet wird
            /// </summary>
            public static void Output(int value)
            {
                Console.Write((char)value);
            }
        }
    Angehängte Dateien Angehängte Dateien
     
    www.iv-interactive.de - Projektewebsite
    WikiParser - aktuelles Projekt

Thema nicht erledigt

Ähnliche Themen

  1. [QUIZ#9] x y z (VB.Net)
    Von Erik im Forum Archiv
    Antworten: 0
    Letzter Beitrag: 20.07.09, 17:16
  2. [QUIZ#7] mAu (PHP)
    Von mAu im Forum Archiv
    Antworten: 0
    Letzter Beitrag: 06.12.08, 14:09
  3. [quiz#1] Kd3 (php)
    Von KD3 im Forum Archiv
    Antworten: 6
    Letzter Beitrag: 22.09.08, 20:11
  4. Quiz
    Von alkaline im Forum PHP
    Antworten: 0
    Letzter Beitrag: 27.09.04, 10:16