/// <summary> /// Метод логирования результатов работы лексического анализатора /// </summary> /// <param name="lexicalAnalysisResult">Результат лексического анализа</param> public void logLexicalAnalysis(LexicalAnalysisResult lexicalAnalysisResult) { if (!lexicalAnalysisResult.isCorrect) { foreach (string str in lexicalAnalysisResult.output) { loggerComponent.AppendText(str); } loggerComponent.AppendText("\n----------\nНайдено некорректное выражение. Работа анализатора остановлена\n"); } else { if (noLogMode) { return; } loggerComponent.AppendText("\n----------\nРезультаты лексического анализа\n-----------\n"); loggerComponent.AppendText("Лексический анализ успешно выполнен\n"); } }
private LexicalAnalysisResult AddMissingSymbols(LexicalAnalysisResult lexicalAnalysisResult) { var lexemesList = lexicalAnalysisResult.Lexemes.ToList(); var terminalSymbolsList = lexicalAnalysisResult.TerminalSymbols.ToList(); // Insert zero value operand between operation start, and addition or negation operator followed by // operand, opening parenthesis, variable storage character or unary operator if (terminalSymbolsList.Count > 1 && (terminalSymbolsList[0] == TerminalSymbol.AdditionOperator || terminalSymbolsList[0] == TerminalSymbol.SubstractionOperator) && (terminalSymbolsList[1] == TerminalSymbol.RealNumber || terminalSymbolsList[1] == TerminalSymbol.OpeningParenthesis || (_terminalSymbolsGroups.TryGetValue(terminalSymbolsList[1], out var tsg) && (tsg == TerminalSymbolGroup.VariableStorageCharacters || tsg == TerminalSymbolGroup.UnaryOperators)))) { lexemesList.Insert(0, ZeroString); terminalSymbolsList.Insert(0, TerminalSymbol.RealNumber); } for (int i = 0; i < terminalSymbolsList.Count - 1; i++) { // Insert multiplication operator between operand, closing parenthesis or variable storage char, // and opening parenthesis, variable storage character or unary operator if ((terminalSymbolsList[i] == TerminalSymbol.RealNumber || terminalSymbolsList[i] == TerminalSymbol.ClosingParenthesis || (_terminalSymbolsGroups.TryGetValue(terminalSymbolsList[i], out var leftTsg) && leftTsg == TerminalSymbolGroup.VariableStorageCharacters)) && (terminalSymbolsList[i + 1] == TerminalSymbol.OpeningParenthesis || (_terminalSymbolsGroups.TryGetValue(terminalSymbolsList[i + 1], out var rightTsg) && (rightTsg == TerminalSymbolGroup.VariableStorageCharacters || rightTsg == TerminalSymbolGroup.UnaryOperators)))) { i++; lexemesList.Insert(i, _operators[TerminalSymbol.MultiplicationOperator].Symbol); terminalSymbolsList.Insert(i, TerminalSymbol.MultiplicationOperator); continue; } // Introduce prioritary negation operation between operator and negation operator followed by // operand, opening parenthesis, variable storage character or unary operator, // replacing the negation operator with the prioritary negation operation if (i < terminalSymbolsList.Count - 2 && _terminalSymbolsGroups.TryGetValue(terminalSymbolsList[i], out leftTsg) && (terminalSymbolsList[i] == TerminalSymbol.OpeningParenthesis || leftTsg == TerminalSymbolGroup.BinaryOperators || leftTsg == TerminalSymbolGroup.UnaryOperators) && terminalSymbolsList[i + 1] == TerminalSymbol.SubstractionOperator && (terminalSymbolsList[i + 2] == TerminalSymbol.RealNumber || terminalSymbolsList[i + 2] == TerminalSymbol.OpeningParenthesis || (_terminalSymbolsGroups.TryGetValue(terminalSymbolsList[i + 2], out rightTsg) && (rightTsg == TerminalSymbolGroup.VariableStorageCharacters || rightTsg == TerminalSymbolGroup.UnaryOperators)))) { i++; lexemesList[i] = _operators[TerminalSymbol.OperandNegatorOperator].Symbol; terminalSymbolsList[i] = TerminalSymbol.OperandNegatorOperator; lexemesList.Insert(i, MinusOneString); terminalSymbolsList.Insert(i, TerminalSymbol.RealNumber); continue; } } return(new LexicalAnalysisResult(lexemesList.ToArray(), terminalSymbolsList.ToArray())); }
private SyntaxAndSemanticAnalysisResult SyntaxAndSemanticAnalysis(Dictionary <string, decimal> variableStorageValues, LexicalAnalysisResult lexicalAnalysisResult) { // Data structures and main variables for syntax analysis var syntaxQueue = new Queue <TerminalSymbol>(lexicalAnalysisResult.TerminalSymbols); syntaxQueue.Enqueue(TerminalSymbol.Nothing); var queueElement = syntaxQueue.Dequeue(); var syntaxStack = new Stack <Enum>(); syntaxStack.Push(TerminalSymbol.Nothing); syntaxStack.Push(_startingNonTerminalSymbol); // Data structures for semantic analysis var operatorsStack = new Stack <Operator>(); var postfixOperation = new List <MathObject>(); while (true) { var stackElement = syntaxStack.Pop(); if (stackElement is TerminalSymbol stackElementTs) { switch (stackElementTs) { case TerminalSymbol.OpeningParenthesis: case TerminalSymbol.ClosingParenthesis: ProcessMathOperator(operatorsStack, postfixOperation, _operators[queueElement]); break; case TerminalSymbol.RealNumber: postfixOperation.Add(new Operand(decimal.Parse(lexicalAnalysisResult.Lexemes[^ syntaxQueue.Count])));
private void button_process_Click(object sender, EventArgs e) { var watch = Stopwatch.StartNew(); loggingService = new LoggingService(richTextBox_log); loggingService.noLogMode = checkBox_measureExecutionTime.Checked; clearWorkplace(); //Init int and fuzzy variables VariablesStorage variablesStorage = InitVariablesService.initVariables(dataGridView_intVariables.Rows, dataGridView_intVariables.NewRowIndex, loggingService); //Select fuzzy variables by their names FuzzyVariableSelectionResult selectionResult = fuzzyVariableService.makeSelection(variablesStorage); if (!selectionResult.isSuccess) { loggingService.logFuzzySelectionError(selectionResult); return; } //Copy int and fuzzy variables into holder variablesStorage_holder.intVariables.AddRange(variablesStorage.intVariables); variablesStorage_holder.fuzzyVariables.AddRange(variablesStorage.fuzzyVariables); //Init expressions expressionsStorage.AddRange( InitExpressionsService.initExpressions(dataGridView_expressions.Rows, dataGridView_expressions.NewRowIndex, loggingService) ); foreach (Expression expression in expressionsStorage) { //Checking IF expression List <Lexeme> ifParserResult = ParserService.parseIfExpression(expression.ifExpressionText); loggingService.logIfParser(expression.ifExpressionText, ifParserResult); //Checking parser result on fuzzy values existence FuzzyVariableSelectionResult ifSelectionResult = fuzzyVariableService.makeSelection(ifParserResult); if (!ifSelectionResult.isSuccess) { loggingService.logFuzzySelectionError(ifSelectionResult); return; } //Checking semantic LexicalAnalysisResult semanticResult = LexicalAnalysisService.makeSemanticAnalysis(ifParserResult, variablesStorage); loggingService.logLexicalAnalysis(semanticResult); //Next steps are available only if semantic analysis is correct if (!semanticResult.isCorrect) { return; } //Sorting by reverse polish notation List <Lexeme> reversePolishNotationLexemeList = ReversePolishNotationService.createNotation(ifParserResult); loggingService.logReversePolishNotation(reversePolishNotationLexemeList); //Creating subexpressions List <Subexpression> currentSubexpressions = subexpressionService.createSubexpressionsList(reversePolishNotationLexemeList, expression.expressionLevel); loggingService.logSubexpressions(currentSubexpressions); subexpressions.AddRange(currentSubexpressions); //Checking THEN expression List <Lexeme> thenParserResult = ParserService.parseThenOrElseExpression(expression.thenExpressionText); loggingService.logThenOrElseParser(expression.thenExpressionText, thenParserResult, true); //Variable assignment //We should assign variables now to correctly mark duplicates //We have no idea now whether THEN or ELSE expression will be executed LexicalAnalysisService.assignVariables(thenParserResult, variablesStorage, expression.expressionLevel); loggingService.logAssignedVariables(variablesStorage, true); //Select fuzzy variables by their names FuzzyVariableSelectionResult thenSelectionResult = fuzzyVariableService.makeSelection(variablesStorage); if (!thenSelectionResult.isSuccess) { loggingService.logFuzzySelectionError(thenSelectionResult); return; } //Checking ELSE expression List <Lexeme> elseParserResult = ParserService.parseThenOrElseExpression(expression.elseExpressionText); loggingService.logThenOrElseParser(expression.elseExpressionText, elseParserResult, false); LexicalAnalysisService.assignVariables(elseParserResult, variablesStorage, expression.expressionLevel); loggingService.logAssignedVariables(variablesStorage, true); //Select fuzzy variables by their names FuzzyVariableSelectionResult elseSelectionResult = fuzzyVariableService.makeSelection(variablesStorage); if (!elseSelectionResult.isSuccess) { loggingService.logFuzzySelectionError(elseSelectionResult); return; } } //Marking duplicates DuplicateExpressionService.markDuplicates(subexpressions, variablesStorage); loggingService.logDuplicates(subexpressions); if (!checkBox_disableBoosters.Checked) { //Precalculating duplicates subexpressionService.calculateDuplicates(subexpressions, variablesStorage, !checkBox_disableBoosters.Checked); loggingService.logDuplicatesValues(subexpressions); } //Restore int variables storage to init state variablesStorage.Clear(); variablesStorage.intVariables.AddRange(variablesStorage_holder.intVariables); variablesStorage.fuzzyVariables.AddRange(variablesStorage_holder.fuzzyVariables); //Calculating major subexpressions one by one //TODO: check level and compare it with local counter to avoid wrong order foreach (Subexpression subexpression in subexpressions) { if (subexpression.major) { //Calculate subexpression subexpression.value = subexpressionService.calculateSubexpressionValue(subexpression, variablesStorage, !checkBox_disableBoosters.Checked); //Prepare int variables storage to next iteration List <Lexeme> parserResult; if (subexpression.value.Value) { parserResult = ParserService.parseThenOrElseExpression(expressionsStorage[subexpression.expressionLevel - 1].thenExpressionText); } else { parserResult = ParserService.parseThenOrElseExpression(expressionsStorage[subexpression.expressionLevel - 1].elseExpressionText); } LexicalAnalysisService.assignVariables(parserResult, variablesStorage, subexpression.expressionLevel); //Select fuzzy variables by their names FuzzyVariableSelectionResult sfvSelectionResult = fuzzyVariableService.makeSelection(variablesStorage); if (!sfvSelectionResult.isSuccess) { loggingService.logFuzzySelectionError(sfvSelectionResult); return; } } } loggingService.logString("------========РЕЗУЛЬТАТЫ:========---------\n"); loggingService.logSubexpressions(subexpressions); loggingService.noLogMode = false; loggingService.logAssignedVariables(variablesStorage, false); watch.Stop(); if (checkBox_measureExecutionTime.Checked) { loggingService.logExecutionTime(watch.ElapsedMilliseconds); } }