Website Summary Files Commits Branches @commit @diff @stats
path: root / homework / 81568 / c2html / cyclomatic.cpp
diff options
context:
space:
mode:
Commit65c7618c2a8834616b009195f10c6cd762f43b8a (patch)
Author
 Mincho Paskalev <minchopaskal@gmail.com>
2018-11-07 10:31:59 +0200
Committer
 dtrendafilov <trendafilov.dn@gmail.com>
2018-11-07 10:31:59 +0200
Files57440acdc2731e7b060928881fa55e983d83f956 /homework/81568/c2html/cyclomatic.cpp
IPL-65c7618c2a8834616b009195f10c6cd762f43b8a.tar
IPL-65c7618c2a8834616b009195f10c6cd762f43b8a.tar.gz
IPL-65c7618c2a8834616b009195f10c6cd762f43b8a.zip
Parent2044770601dff8f1bd1c6cb9d0617f669b430e1d (diff)
Добавяне на второ домашно (#30)
* 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
1 files changed, 95 insertions, 0 deletions
-rw-r--r--homework/81568/c2html/cyclomatic.cpp95
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 <stack>
+
+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<short> history;
+ bool inFunction = false;
+
+ #define PAREN false
+ std::stack<bool> 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("<!-- ", out);
+ char closingDiv[100];
+ sprintf(closingDiv, "%d --></div>", 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, "<div class=\"func\">", className.c_str());
+ fputs(openingDiv, out);
+ inFunction = true;
+ history = std::stack<short>{};
+ }
+ }
+ }
+
+ if (!writeToOutput(out, currentToken))
+ break;
+ lexeme = "";
+ number = 0.0;
+ } while (type != TokenClass::Eof ||
+ type != TokenClass::Invalid);
+ return counter - 1;
+}