From 65c7618c2a8834616b009195f10c6cd762f43b8a Mon Sep 17 00:00:00 2001 From: Mincho Paskalev Date: Wed, 7 Nov 2018 10:31:59 +0200 Subject: Добавяне на второ домашно (#30) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add 1st hw * --amend * moving readme for 1st hw to designated folder * renamed TokenType enum to TokenClass * fixed character constant lexing. added sampe output file * add new line at end-of-file. added gitignore * a bit of refactoring * adding cyclomatic complexity * refactored * adding cyclomatic complexity * refactored --- homework/81568/c2html/cyclomatic.cpp | 95 ++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 homework/81568/c2html/cyclomatic.cpp (limited to 'homework/81568/c2html/cyclomatic.cpp') diff --git a/homework/81568/c2html/cyclomatic.cpp b/homework/81568/c2html/cyclomatic.cpp new file mode 100644 index 0000000..b7b0c17 --- /dev/null +++ b/homework/81568/c2html/cyclomatic.cpp @@ -0,0 +1,95 @@ +#include "cyclomatic.h" +#include "html_utils.h" +#include "lexcer.h" +#include "lexconst.h" +#include + +using HTMLUtils::writeToOutput; +using LexCer::TokenClass; +using LexCer::Tokenizer; + +// Writing a full parser would give us the change of +// making the cyclomatic graph of the function. +// #courseproject +unsigned ParCer::outputWithCyclomaticComplexity(FILE *in, FILE *out) { + Tokenizer tokenizer (in, out); + + std::string lexeme; + double number; + TokenClass type; + Token currentToken; + std::stack history; + bool inFunction = false; + + #define PAREN false + std::stack openedBlocks; + std::string className = "a"; + unsigned counter = 1; + unsigned complexity = 1; + + do { + currentToken = tokenizer.nextToken(&lexeme, &number); + type = currentToken.type; + + if (!inFunction) { + history.push(type); + } else { + if (type == TokenClass::RightCurly) { + if (openedBlocks.empty()) { // end of a function. What one does to avoid parsing 'C' + inFunction = false; + fputs("", complexity); + fputs(closingDiv, out); + complexity = 1; + } else { + openedBlocks.pop(); + } + } + else if (type == TokenClass::LeftCurly) { + openedBlocks.push(PAREN); + } + else if (type == TokenClass::Keyword) { + if (!lexeme.compare("if") || + !lexeme.compare("while") || + !lexeme.compare("for") || + !lexeme.compare("case") || + !lexeme.compare("default")) + { + ++complexity; + } + } + } + + if (!inFunction && type == TokenClass::LeftCurly) { + history.pop(); + while (!history.empty() && history.top() == TokenClass::Skip) { + history.pop(); + } + + if (history.top() == TokenClass::RightParen) { + while (!history.empty() && history.top() != TokenClass::LeftParen) + history.pop(); + if (!history.empty()) + history.pop(); + while (!history.empty() && history.top() == TokenClass::Skip) + history.pop(); + + if (!history.empty() && history.top() == TokenClass::Identifier) { // We are in a function + char openingDiv[100]; + sprintf(openingDiv, "
", className.c_str()); + fputs(openingDiv, out); + inFunction = true; + history = std::stack{}; + } + } + } + + if (!writeToOutput(out, currentToken)) + break; + lexeme = ""; + number = 0.0; + } while (type != TokenClass::Eof || + type != TokenClass::Invalid); + return counter - 1; +} -- cgit v1.3.1-23-gd82d