Skip to content

Commit

Permalink
Проверка порядка скобок, цифр, операторов.
Browse files Browse the repository at this point in the history
Добавил поддержку булевой алгебры.
  • Loading branch information
rincew1nd committed Nov 24, 2016
1 parent 56bc70c commit a9e58d7
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 22 deletions.
16 changes: 11 additions & 5 deletions CodeTranslator/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,25 @@
<Run Text="Программа"/>
</Paragraph>
<Paragraph>
<Run Text="Метки 10 20 30 40"/>
<Run Text="Метки 10 20 30 40 50 60 70"/>
</Paragraph>
<Paragraph>
<Run Text="10 : йцук1 = 123 + 123"/>
<Run Text="10 : йцук1 = 123+123"/>
</Paragraph>
<Paragraph>
<Run Text="20 : йцук2 = 123 - 123"/>
<Run Text="20 : йцук2 = 123-123"/>
</Paragraph>
<Paragraph>
<Run Text="30 : йцук3 = 234 / 2"/>
<Run Text="30 : йцук3 = 234/2"/>
</Paragraph>
<Paragraph>
<Run Text="40 : йцук4 = 234 * 2"/>
<Run Text="40 : йцук4 = 234*2"/>
</Paragraph>
<Paragraph>
<Run Text="50 : йцук5 = (10+5)/(54+5)"/>
</Paragraph>
<Paragraph>
<Run Text="60 : йцук6 = ((10+5)/(54+5))/0.2"/>
</Paragraph>
<Paragraph>
<Run Text="Конец программа"/>
Expand Down
115 changes: 100 additions & 15 deletions CodeTranslator/Translator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,20 @@ public Translator()
{
_regexs = new Dictionary<string, Regex>()
{
{"Числa", new Regex("^[0-9]+$")},
{"БульевыЧислa", new Regex("^[!0-9]+$")},
{"Буквы", new Regex("^[а-яА-Я]+$")},
{"Переменная", new Regex($"^[0-9а-яА-Я]+$")},
{"Скобки", new Regex(@"^\(.+\)$")},
{"Числa", new Regex(@"^\d+$")},
{"Операторы", new Regex("[&|*/+-]") },

{"БульевыЧислa", new Regex("[!01]+")},
{"БульевыЗнаки", new Regex("[!&|]")},
{"БулеваОперация", new Regex("[!&|01]+")},

{"ЯзыкНачало", new Regex("^Программа$")},
{"ЯзыкКонец", new Regex("^Конец программа$")},
{"Заголовок", new Regex($"^Метки( [0-9]+)+$")},
{"Операция", new Regex("^([0-9]+) : ([0-9а-яА-Я]+) = ([0-9()!&|+*/ -]+)$")},
{"ПравЧасть", new Regex("^([0-9()!&|+*/ -]+) ([!&|+*/-]) ([0-9()!&|+*/ -]+)$")},
{"ПравЧастьТочка", new Regex("^([0-9()!&|+*/, -]+) ([!&|+*/-]) ([0-9()!&|+*/, -]+)$")}
{"Заголовок", new Regex(@"^Метки( [\d]+)+$")},
{"Операция", new Regex(@"^([\d]+) : ([\dа-яА-Я]+) = ([\d()!&|+*/ -]+)$")},
{"ПраваяЧасть", new Regex(@"^([\d()!&|+*/,-]+)([&|+*/-])([\d()!&|+*/,-]+)$")},
{"ПраваяЧастьПростая", new Regex(@"^(-?\d+,?\d*?)(([+*/-])(-?\d+,?\d*?))+$")},
{"ПраваяЧастьБуль", new Regex(@"^(!?[0-1]+)(([|&])(!?[0-1]+))+$")}
};

_errorsDic = new Dictionary<string, string>()
Expand Down Expand Up @@ -88,7 +90,7 @@ public string CheckSyntax(string text)
if (_variables.ContainsKey(groups[2].Value))
return "Такая переменная уже была объявлена ранее!";

if (_regexs["ПравЧастьТочка"].IsMatch(groups[3].Value))
if (_regexs["ПраваяЧасть"].IsMatch(groups[3].Value))
_variables.Add(groups[2].Value, double.Parse(ParseOperation(groups[3].Value)));
codeLineNum++;
}
Expand Down Expand Up @@ -149,30 +151,106 @@ private string ParseOperation(string text)

private void CheckBrackets(string text)
{
var brackets = new[] { '(', ')' };
var operationType = _regexs["БульевыЗнаки"].IsMatch(text) ?
"ПраваяЧастьБуль" : "ПраваяЧастьПростая";

if (text.Count(c => c == ')') != text.Count(c => c == '('))
throw new ArgumentException("Есть непарные скобки");

if (operationType == "ПраваяЧастьБуль")
if (!_regexs["БулеваОперация"].IsMatch(text))
throw new Exception("Булева операция содержит недопустимые символы");

var openBracketCount = 0;
var lastBracketContent = new StringBuilder();
foreach (var chr in text)
{
if (brackets.Contains(chr))
{
if (chr == '(')
{
openBracketCount++;
if (lastBracketContent.Length != 0)
{
var lastSymbol = lastBracketContent.ToString().Last().ToString();
if (lastSymbol == "(" || _regexs["Операторы"].IsMatch(lastSymbol))
continue;

if (_regexs["Числа"].IsMatch(lastSymbol))
throw new Exception("Fuck you bracket operator!");
if (lastSymbol == ")")
throw new Exception("Fuck you close bracket!");
}
}
else
{
if (openBracketCount == 0)
throw new Exception("Close bracket without fking open bracket! Damn~");

openBracketCount--;
if (lastBracketContent.Length != 0)
{
var lastSymbol = lastBracketContent.ToString().Last().ToString();
if (lastSymbol == ")" || _regexs["Числa"].IsMatch(lastSymbol))
if (_regexs[operationType].IsMatch(lastBracketContent.ToString()))
continue;
else throw new Exception("Fuck number-operator order!");

if (lastSymbol == "(")
throw new Exception("Fuck empty brackets!~");
if (_regexs["Операторы"].IsMatch(lastSymbol))
throw new Exception("Fuck operator before bracket!~");
} else
throw new Exception("Fuck first close bracket character!~");
}
}
else
lastBracketContent.Append(chr);
}

if (!_regexs[operationType].IsMatch(lastBracketContent.ToString()))
throw new Exception("Fuck number-operator order!");
}

private string PerformCalculation(string operation)
{
var operType1 = new[] { "/", "*" };
var operType2 = new[] { "-", "+" };

var opers = OperatorsArray(operation);
while (opers.Length != 1)
{
if (opers.Contains("/") || opers.Contains("*"))
if (opers.Count(c => operType1.Contains(c)) > 0)
{
RecurciveReplacing(ref opers, new[] { "*", "/" });
RecurciveReplacing(ref opers, operType1);
}
else
else if (opers.Count(c => operType2.Contains(c)) > 0)
{
RecurciveReplacing(ref opers, operType2);
}
else if (opers.Count(c => c.StartsWith("!")) > 0)
{
RecurciveReplacing(ref opers, new [] {"+", "-"});
ReplaceBoolInversion(ref opers);
}
else if (opers.Contains("&"))
{
RecurciveReplacing(ref opers, new[] { "&" });
}
else if (opers.Contains("|"))
{
RecurciveReplacing(ref opers, new[] { "|" });
}
}
return opers[0];
}

private string[] OperatorsArray(string operation)
{
var opersRegex = Regex.Match(operation, @"^(-?[0-9]+,?[0-9]*?)(([+*/-])(-?[0-9]+,?[0-9]*?))+$");
var operationType = _regexs["БульевыЗнаки"].IsMatch(operation) ?
"ПраваяЧастьБуль" : "ПраваяЧастьПростая";

var opersRegex = _regexs[operationType].Match(operation);

var opers = new string[1];
opers[0] = opersRegex.Groups[1].Value;
Expand Down Expand Up @@ -202,6 +280,13 @@ private void RecurciveReplacing(ref string[] opers, string[] oper)
}
}

public void ReplaceBoolInversion(ref string[] opers)
{
for (var i = 0; i < opers.Length; i++)
if (opers[i].StartsWith("!"))
opers[i] = opers[i] == "!1" ? "0" : "1";
}

private double Calculate(string leftSide, string oper, string rightSide)
{
if (new [] { "&", "|", "!" }.Contains(oper) &&
Expand Down
14 changes: 12 additions & 2 deletions UnitTests/Calculations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,18 @@ public void BooleanCalculation()
public void AlotOfBrackets()
{
var translator = new Translator();
translator.PrivateMethod("ParseOperation", "((12-43*(3-1)-10)-12)-34+34-(9/2)");
translator.PrivateMethod("ParseOperation", "((12-43*(3-1)-10)-12)-34+34-(8/2)");
Assert.AreEqual(
translator.PrivateMethod("ParseOperation", "((12-43*(3-1)-10)-12)-34+34-(9/2)"), "-100,5");
Assert.AreEqual(
translator.PrivateMethod("ParseOperation", "((12-43*(3-1)-10)-12)-34+34-(8/2)"), "-100");
}

[Test]
public void BooleanAlgebra()
{
var translator = new Translator();
Assert.AreEqual(translator.PrivateMethod("ParseOperation", "!1|0&(1|0)"), "0");
Assert.AreEqual(translator.PrivateMethod("ParseOperation", "(1&!0)|(0|!1)"), "1");
}
}
}

0 comments on commit a9e58d7

Please sign in to comment.