Exemple #1
0
        /// <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");
            }
        }
Exemple #2
0
        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()));
        }
Exemple #3
0
        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])));
Exemple #4
0
        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);
            }
        }