ERLEDIGT
NEIN
NEIN
ANTWORTEN
4
4
ZUGRIFFE
190
190
EMPFEHLEN
-
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); } }
Geändert von Spyke (03.10.08 um 18:24 Uhr)
-
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); } }
Geändert von Spyke (03.10.08 um 15:56 Uhr)
-
Die angehängten Zip Dateien öffnen und die BFEditor.exe starten.
In dem Textfeld kann dann rumprobiert werden.
-
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
-
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); } }
Ähnliche Themen
-
[QUIZ#9] x y z (VB.Net)
Von Erik im Forum ArchivAntworten: 0Letzter Beitrag: 20.07.09, 17:16 -
[QUIZ#7] mAu (PHP)
Von mAu im Forum ArchivAntworten: 0Letzter Beitrag: 06.12.08, 14:09 -
[quiz#1] Kd3 (php)
Von KD3 im Forum ArchivAntworten: 6Letzter Beitrag: 22.09.08, 20:11 -
Quiz
Von alkaline im Forum PHPAntworten: 0Letzter Beitrag: 27.09.04, 10:16





Login





