Zum testen am besten den letzten Dateianhang dieses Thread verwenden.
Die erste Version des Interpreters läuft mit Hilfe von Regular Expression
Der Interpreter
Aufruf:
Die erste Version des Interpreters läuft mit Hilfe von Regular Expression
Der Interpreter
C#:
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:
C#:
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);
}
}
Anhänge
Zuletzt bearbeitet von einem Moderator: