Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //в этом списке будут лежать все арифметические выражения в матричном виде. одна строка на одно выражение.
- public List<string> ExpMatrix { get; }
- private readonly Stack<ExpOperand> _operands;
- private readonly Stack<Node> _operators;
- private int _currentRuleId;
- ......
- /// <summary>
- /// Выполянет разбор афирметичскеого выражения.
- /// </summary>
- private void ParseExpression()
- {
- _currentRuleId = 1;
- _operators.Clear();
- _operands.Clear();
- while (true)
- {
- var inputToken = _currentToken;
- if (IsOperand(inputToken)) AddNode();
- else
- {
- var currentOperation = _operators.Count > 0 ? _operators.Peek().Name : null;
- if (!IsOperator(inputToken))
- {
- switch (currentOperation)
- {
- case null:
- if (_operands.Count == 1)
- {
- var mainNode = _operands.Pop();
- ExpMatrix.Add(mainNode.BuildMatrix());
- _holder.Push(new Node(){Name = "Expression", Type = Type.Expression});
- return;
- }
- else ThrowExpressionError("Ошибка в выражении.");
- break;
- case "(":
- ThrowExpressionError("Не хватает закрывающей скобки.");
- break;
- case "-":
- case "+":
- case "*":
- case "/":
- ActionD4();
- break;
- }
- }
- else
- {
- switch (inputToken.Name)
- {
- case "(":
- ActionD1();
- break;
- case "-":
- case "+":
- switch (currentOperation)
- {
- case null:
- case "(":
- ActionD1();
- break;
- case "+":
- case "-":
- ActionD2();
- break;
- case "*":
- case "/":
- ActionD4();
- break;
- }
- break;
- case "*":
- case "/":
- switch (currentOperation)
- {
- case null:
- case "(":
- case "+":
- case "-":
- ActionD1();
- break;
- case "*":
- case "/":
- ActionD2();
- break;
- }
- break;
- case ")":
- switch (currentOperation)
- {
- case null:
- ThrowExpressionError("Не хватает открывающей скобки.");
- break;
- case "(":
- ActionD3();
- break;
- case "+":
- case "-":
- case "*":
- case "/":
- ActionD4();
- break;
- }
- break;
- }
- }
- }
- }
- }
- private void ActionD1()
- {
- _operators.Push(_currentToken);
- ReadNext();
- }
- private void ActionD2()
- {
- var op1 = _operators.Pop();
- MakeNode(op1);
- _operators.Push(_currentToken);
- ReadNext();
- }
- private void ActionD3()
- {
- _operators.Pop();
- ReadNext();
- }
- private void ActionD4()
- {
- var op1 = _operators.Pop();
- MakeNode(op1);
- }
- /// <summary>
- /// Создаёт новый узел на основе указанного оператора, а также двух первых операндов на вершине стека.
- /// </summary>
- /// <param name="oper"></param>
- private void MakeNode(Node oper)
- {
- if (_operands.Count < 2) ThrowExpressionError("Пропущены операнды.");
- var right = _operands.Pop();
- var left = _operands.Pop();
- var n = new ExpOperand(oper, left, right, $"M{_currentRuleId++}");
- _operands.Push(n);
- }
- /// <summary>
- /// Создаёт новый узел на основе текущего токена.
- /// </summary>
- private void AddNode()
- {
- var cur = _currentToken;
- Debug.Assert(IsOperand(cur));
- var node = new ExpOperand(cur, null, null);
- _operands.Push(node);
- ReadNext();
- }
- /// <summary>
- /// Проверяет, являеся ли указанный токен операндом.
- /// </summary>
- /// <param name="token"></param>
- /// <returns></returns>
- private static bool IsOperand(Node token)
- {
- switch (token.Type)
- {
- case Type.Literal:
- case Type.Identifier:
- return true;
- default:
- return false;
- }
- }
- /// <summary>
- /// Проверяет, является ли указанный токен оператором.
- /// </summary>
- /// <param name="t"></param>
- /// <returns></returns>
- public static bool IsOperator(Node t)
- {
- switch (t.Name)
- {
- case "-":
- case "+":
- case "/":
- case "(":
- case ")":
- case "*":
- return true;
- default:
- return false;
- }
- }
- /// <summary>
- /// Проверяет, является ли токен оператором или операндом.
- /// </summary>
- /// <param name="t"></param>
- /// <returns></returns>
- public static bool IsExpression(Node t) => IsOperand(t) || IsOperator(t);
- private static void ThrowExpressionError(string desc)
- {
- throw new Exception("Ошибка в арифметическом выражении!\n" +
- $"Описание: {desc}");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement