diff options
| Commit | 65c7618c2a8834616b009195f10c6cd762f43b8a (patch) | |
|---|---|---|
| Author | 2018-11-07 10:31:59 +0200 | |
| Committer | 2018-11-07 10:31:59 +0200 | |
| Files | 57440acdc2731e7b060928881fa55e983d83f956 | |
| IPL-65c7618c2a8834616b009195f10c6cd762f43b8a.tar IPL-65c7618c2a8834616b009195f10c6cd762f43b8a.tar.gz IPL-65c7618c2a8834616b009195f10c6cd762f43b8a.zip | ||
| Parent | 2044770601dff8f1bd1c6cb9d0617f669b430e1d (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
11 files changed, 428 insertions, 212 deletions
| -rw-r--r-- | homework/81568/c2html/Makefile | 4 | ||||
| -rw-r--r-- | homework/81568/c2html/cyclomatic.cpp | 95 | ||||
| -rw-r--r-- | homework/81568/c2html/cyclomatic.h | 19 | ||||
| -rw-r--r-- | homework/81568/c2html/html_utils.cpp | 87 | ||||
| -rw-r--r-- | homework/81568/c2html/html_utils.h | 18 | ||||
| -rw-r--r-- | homework/81568/c2html/lexcer.cpp | 178 | ||||
| -rw-r--r-- | homework/81568/c2html/lexcer.h | 18 | ||||
| -rw-r--r-- | homework/81568/c2html/lexconst.h | 3 | ||||
| -rw-r--r-- | homework/81568/c2html/main.cpp | 51 | ||||
| -rw-r--r-- | homework/81568/c2html/test.c | 6 | ||||
| -rw-r--r-- | homework/81568/c2html/test.html | 161 |
diff --git a/homework/81568/c2html/Makefile b/homework/81568/c2html/Makefile index d41a5a4..2856500 100644 --- a/homework/81568/c2html/Makefile +++ b/homework/81568/c2html/Makefile @@ -1,2 +1,2 @@ -lexcer: main.cpp lexcer.cpp - g++ -o lexcer main.cpp lexcer.cpp +lexcer: main.cpp lexcer.cpp cyclomatic.cpp html_utils.cpp + g++ -o lexcer main.cpp lexcer.cpp cyclomatic.cpp html_utils.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 <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; +} diff --git a/homework/81568/c2html/cyclomatic.h b/homework/81568/c2html/cyclomatic.h new file mode 100644 index 0000000..29fdc1c --- /dev/null +++ b/homework/81568/c2html/cyclomatic.h @@ -0,0 +1,19 @@ +#ifndef CYCLOMATIC_H +#define CYCLOMATIC_H + +#include <cstdio> + +// Given this +// is 20,000 LOC, I'll probably leave parsing +// 'C' as a course project +// #courseproject + +// class Parser; + +namespace ParCer { + +unsigned outputWithCyclomaticComplexity(FILE *fpIn, FILE *fpOut); + +} /* Namespace ParCer */ + +#endif /* CYCLOMATIC_H */ diff --git a/homework/81568/c2html/html_utils.cpp b/homework/81568/c2html/html_utils.cpp new file mode 100644 index 0000000..6ca91c6 --- /dev/null +++ b/homework/81568/c2html/html_utils.cpp @@ -0,0 +1,87 @@ +#include "html_utils.h" +#include "lexconst.h" + +namespace HTMLUtils { + +std::string escapeHTML(const std::string &lexeme) { + std::string result; + for (auto c : lexeme) { + switch(c) { + case '<': + result.append("<"); + break; + case '>': + result.append(">"); + break; + case '&': + result.append("&"); + break; + default: + result.push_back(c); + break; + } + } + return result; +} + +bool writeToOutput(FILE *out, Token token) { + if (token.type == TokenClass::Eof) { + printf("End of file!\n"); + fputc('\n', out); + return false; + } + + if (token.type == TokenClass::Skip) { + if (fputs(token.lexeme.c_str(), out) == EOF) { + printf("Error while writing to output"); + return false; + } + return true; + } + + printf("Token of type %s at line %d: ", LexCer::tokenToClass.at(token.type).c_str(), token.line); + if (token.type == TokenClass::Number) + printf("%f\n", token.number); + else + printf("%s\n", token.lexeme.c_str()); + + auto lexeme = escapeHTML(token.lexeme); + + std::string output; + output.append(LexCer::spanBegin).append(LexCer::tokenToClass.at(token.type)).append("\">").append(lexeme).append(LexCer::spanEnd); + + if (fputs(output.c_str(), out) == EOF) { + printf("Error while writing to output"); + return false; + } + return true; +} + +std::string getOutputFileName(const std::string &name) { + auto pos = name.find_last_of('.'); + if (pos == std::string::npos) { + return name + ".html"; + } + + return name.substr(0, pos) + ".html"; +} + +void lexCit(FILE *in, FILE *out) { + Tokenizer hl {in, out}; + + std::string lexeme; + double number; + TokenClass type; + Token token; + do { + token = hl.nextToken(&lexeme, &number); + type = token.type; + + if (!writeToOutput(out, token)) + break; + lexeme = ""; + number = 0.0; + } while(type != TokenClass::Eof || type != TokenClass::Invalid); +} + +} /* Namespace HTMLUtils */ diff --git a/homework/81568/c2html/html_utils.h b/homework/81568/c2html/html_utils.h new file mode 100644 index 0000000..8d8cf0d --- /dev/null +++ b/homework/81568/c2html/html_utils.h @@ -0,0 +1,18 @@ +#ifndef HTML_UTILS_H +#define HTML_UTILS_H + +#include "lexcer.h" +using LexCer::Token; +using LexCer::TokenClass; +using LexCer::Tokenizer; + +namespace HTMLUtils { + +std::string escapeHTML(const std::string &lexeme); +bool writeToOutput(FILE *out, Token token); +std::string getOutputFileName(const std::string &name); +void lexCit(FILE *in, FILE *out); + +} /* Namespace HMTLUtils */ + +#endif /* HTML_UTILS_H */ diff --git a/homework/81568/c2html/lexcer.cpp b/homework/81568/c2html/lexcer.cpp index 6ad3dbd..df28e6f 100644 --- a/homework/81568/c2html/lexcer.cpp +++ b/homework/81568/c2html/lexcer.cpp @@ -4,30 +4,22 @@ #include <cctype> #include <cstdlib> -// using LexCer::TokenClass; -// using LexCer::Token; -// using LexCer::keywords; -// using LexCer::preprocessor; -// using LexCer::tokenToClass; -// using LexCer::spanBegin; -// using LexCer::spanEnd; - -//const char* Tokenizer::spanBegin = "<span class=\""; -//const char* Tokenizer::spanEnd = "</span>"; - namespace LexCer { Tokenizer::Tokenizer(FILE *in, FILE *out) : in(in), out(out) { token.type = TokenClass::Invalid; - typenames = {"void", "char", "short", "int", "long", "float", "double", "signed", "unsigned"}; + // The idea behind having modifiable typenames structure was to read #defines, but + // maybe it is better if a whole preproccessor is written. + typenames = {"void", "char", "short", "int", "long", "float", "double", "signed", "unsigned", "FILE"}; } -void Tokenizer::makeToken(TokenClass type, unsigned line, std::string lexeme, double number) { +Token Tokenizer::makeToken(TokenClass type, std::string lexeme, double number) { token.type = type; token.line = line; token.lexeme = lexeme; token.number = number; + return token; } bool Tokenizer::readNextDirective(std::string *lexeme) { @@ -178,68 +170,15 @@ bool Tokenizer::readUntilBlank(std::string *lexeme) { return true; } -bool Tokenizer::writeToOutput() { - if (token.type == TokenClass::Eof) { - printf("End of file!\n"); - fputc('\n', out); - return false; - } - - if (token.type == TokenClass::Skip) { - if (fputs(token.lexeme.c_str(), out) == EOF) { - printf("Error while writing to output"); - return false; - } - return true; - } - - printf("Token of type %s at line %d: ", tokenToClass.at(token.type).c_str(), token.line); - if (token.type == TokenClass::Number) - printf("%f\n", token.number); - else - printf("%s\n", token.lexeme.c_str()); - - auto lexeme = escapeHTML(token.lexeme); - - std::string output; - output.append(spanBegin).append(tokenToClass.at(token.type)).append("\">").append(lexeme).append(spanEnd); - - if (fputs(output.c_str(), out) == EOF) { - printf("Error while writing to output"); - return false; - } - return true; -} - -std::string Tokenizer::escapeHTML(const std::string &lexeme) { - std::string result; - for (auto c : lexeme) { - switch(c) { - case '<': - result.append("<"); - break; - case '>': - result.append(">"); - break; - case '&': - result.append("&"); - break; - default: - result.push_back(c); - break; - } - } - return result; -} - -TokenClass Tokenizer::nextToken(std::string *lexeme, double *number) { +Token Tokenizer::nextToken(std::string *lexeme, double *number) { + TokenClass type; if (token.type == TokenClass::Eof) { - return TokenClass::Invalid; + return makeToken(TokenClass::Invalid, *lexeme, *number); } char c = fgetc(in); if (c == EOF) { - return TokenClass::Eof; + return makeToken(TokenClass::Eof, *lexeme, *number); } lexeme->push_back(c); // operator || symbol || string || preprocessor directive @@ -251,22 +190,24 @@ TokenClass Tokenizer::nextToken(std::string *lexeme, double *number) { case ' ': case ';': case ',': - case '{': - case '}': - return TokenClass::Skip; + return makeToken(TokenClass::Skip, *lexeme, *number); case '(': - return TokenClass::LeftParen; + return makeToken(TokenClass::LeftParen, *lexeme, *number); case ')': - return TokenClass::RightParen; + return makeToken(TokenClass::RightParen, *lexeme, *number); + case '{': + return makeToken(TokenClass::LeftCurly, *lexeme, *number); + case '}': + return makeToken(TokenClass::RightCurly, *lexeme, *number); case '[': case ']': case '?': case ':': - return TokenClass::Operator; + return makeToken(TokenClass::Operator, *lexeme, *number); case '*': c = fgetc(in); if (c == '/') { - return TokenClass::Invalid; + return makeToken(TokenClass::Invalid, *lexeme, *number); } ungetc((unsigned) c, in); c = '*'; @@ -278,7 +219,7 @@ TokenClass Tokenizer::nextToken(std::string *lexeme, double *number) { c = fgetc(in); if (c != '=') ungetc((unsigned) c, in); else lexeme->push_back(c); - return TokenClass::Operator; + return makeToken(TokenClass::Operator, *lexeme, *number); case '<': case '>': c = fgetc(in); @@ -292,11 +233,11 @@ TokenClass Tokenizer::nextToken(std::string *lexeme, double *number) { } else if (lexeme->at(lexeme->size() - 1) == '<' && isalpha(c)) { lexeme->push_back(c); if (!readInclude(lexeme)) - return TokenClass::Invalid; - return TokenClass::String; + return makeToken(TokenClass::Invalid, *lexeme, *number); + return makeToken(TokenClass::String, *lexeme, *number); } else ungetc((unsigned) c, in); - return TokenClass::Operator; + return makeToken(TokenClass::Operator, *lexeme, *number); case '&': case '|': case '+': @@ -305,18 +246,18 @@ TokenClass Tokenizer::nextToken(std::string *lexeme, double *number) { lexeme->push_back(c); else ungetc((unsigned) c, in); - return TokenClass::Operator; + return makeToken(TokenClass::Operator, *lexeme, *number); case '-': c = fgetc(in); if (c == '-' || c == '=' || c == '>') lexeme->push_back(c); else ungetc((unsigned) c, in); - return TokenClass::Operator; + return makeToken(TokenClass::Operator, *lexeme, *number); case '#': if (readNextDirective(lexeme)) - return TokenClass::PreprocessorDirective; - return TokenClass::Invalid; + return makeToken(TokenClass::PreprocessorDirective, *lexeme, *number); + return makeToken(TokenClass::Invalid, *lexeme, *number); case '\'': lexeme->push_back(c = fgetc(in)); if (c == '\\') { @@ -324,90 +265,63 @@ TokenClass Tokenizer::nextToken(std::string *lexeme, double *number) { } lexeme->push_back(c = fgetc(in)); // the closing mark if (c != '\'') - return TokenClass::Invalid; - return TokenClass::String; + return makeToken(TokenClass::Invalid, *lexeme, *number); + return makeToken(TokenClass::String, *lexeme, *number); case '"': if (readNextString(lexeme, c)) - return TokenClass::String; - return TokenClass::Invalid; + return makeToken(TokenClass::String, *lexeme, *number); + return makeToken(TokenClass::Invalid, *lexeme, *number); case '/': c = fgetc(in); lexeme->push_back(c); switch (c) { case '=': - return TokenClass::Operator; + return makeToken(TokenClass::Operator, *lexeme, *number); case '/': if (!readLineComment(lexeme)) - return TokenClass::Invalid; - return TokenClass::Comment; + return makeToken(TokenClass::Invalid, *lexeme, *number); + return makeToken(TokenClass::Comment, *lexeme, *number); case '*': if (!readMultilineComment(lexeme)) - return TokenClass::Invalid; - return TokenClass::Comment; + return makeToken(TokenClass::Invalid, *lexeme, *number); + return makeToken(TokenClass::Comment, *lexeme, *number); default: if (!isblank(c) || !isdigit(c)) { ungetc((unsigned) c, in); lexeme->pop_back(); - return TokenClass::Invalid; + return makeToken(TokenClass::Invalid, *lexeme, *number); } - return TokenClass::Operator; + return makeToken(TokenClass::Operator, *lexeme, *number); } case '\\': c = fgetc(in); ungetc((unsigned) c, in); if (c != '\n') - return TokenClass::Invalid; // stray '\' - return TokenClass::Operator; + return makeToken(TokenClass::Invalid, *lexeme, *number); // stray '\' + return makeToken(TokenClass::Operator, *lexeme, *number); } // identifier || keyword || typename if (isalpha(c) || c == '_') { if (readNextIdentifier(lexeme)) { if (keywords.count(*lexeme) != 0) - return TokenClass::Keyword; + return makeToken(TokenClass::Keyword, *lexeme, *number); else if (typenames.count(*lexeme) != 0) - return TokenClass::Typename; - return TokenClass::Identifier; + return makeToken(TokenClass::Typename, *lexeme, *number); + return makeToken(TokenClass::Identifier, *lexeme, *number); } else { - return TokenClass::Invalid; + return makeToken(TokenClass::Invalid, *lexeme, *number); } } if (!isdigit(c)) { - return TokenClass::Invalid; + return makeToken(TokenClass::Invalid, *lexeme, *number); } // number if (readNextNumber(c, number, lexeme)) - return TokenClass::Number; - return TokenClass::Invalid; + return makeToken(TokenClass::Number, *lexeme, *number); + return makeToken(TokenClass::Invalid, *lexeme, *number); } - - -std::string getOutputFileName(const std::string &name) { - auto pos = name.find_last_of('.'); - if (pos == std::string::npos) { - return name + ".html"; - } - return name.substr(0, pos) + ".html"; -} - -void lexCit(FILE *in, FILE *out) { - Tokenizer hl {in, out}; - - std::string lexeme; - double number; - TokenClass type; - do { - type = hl.nextToken(&lexeme, &number); - - hl.makeToken(type, hl.lineNumber(), lexeme, number); - if (!hl.writeToOutput()) - break; - lexeme = ""; - number = 0.0; - } while(hl.currentToken().type != TokenClass::Eof || hl.currentToken().type != TokenClass::Invalid); -} - } /* Namespace Lexcer */ diff --git a/homework/81568/c2html/lexcer.h b/homework/81568/c2html/lexcer.h index e329a90..eb8afe0 100644 --- a/homework/81568/c2html/lexcer.h +++ b/homework/81568/c2html/lexcer.h @@ -9,7 +9,7 @@ namespace LexCer { -enum class TokenClass : short { +enum TokenClass : short { Operator, Keyword, PreprocessorDirective, @@ -20,6 +20,8 @@ enum class TokenClass : short { Number, LeftParen, RightParen, + LeftCurly, + RightCurly, Skip, Eof, @@ -46,16 +48,10 @@ private: public: Tokenizer(FILE *in, FILE *out); - unsigned lineNumber() const { return line; } - Token currentToken() const { return token; } - - TokenClass nextToken(std::string *lexeme, double *number); - void makeToken(TokenClass type, unsigned line, - std::string lexeme = std::string(), double number = 0.0); - bool writeToOutput(); + Token nextToken(std::string *lexeme, double *number); private: - std::string escapeHTML(const std::string &lexeme); + Token makeToken(TokenClass type, std::string lexeme = std::string(), double number = 0.0); bool readNextDirective(std::string *lexeme); bool readNextString(std::string *lexeme, char oldc); bool readNextIdentifier(std::string *lexeme); @@ -75,10 +71,6 @@ private: std::unordered_set<std::string> typenames; }; - -std::string getOutputFileName(const std::string &name); -void lexCit(FILE *in, FILE *out); - } /* Namespace LexCer */ #endif diff --git a/homework/81568/c2html/lexconst.h b/homework/81568/c2html/lexconst.h index 9d2068d..cfb9e6d 100644 --- a/homework/81568/c2html/lexconst.h +++ b/homework/81568/c2html/lexconst.h @@ -25,6 +25,9 @@ static const std::unordered_map<TokenClass, std::string> tokenToClass {TokenClass::Number, "number"}, {TokenClass::Invalid, "invalid"}, {TokenClass::LeftParen, "identifier"}, + {TokenClass::LeftCurly, "identifier"}, + {TokenClass::RightParen, "identifier"}, + {TokenClass::RightCurly, "identifier"}, {TokenClass::RightParen, "identifier"} } }; diff --git a/homework/81568/c2html/main.cpp b/homework/81568/c2html/main.cpp index eedaee3..d4dbed3 100644 --- a/homework/81568/c2html/main.cpp +++ b/homework/81568/c2html/main.cpp @@ -1,4 +1,8 @@ #include <cstdio> +#include <cstring> + +#include "cyclomatic.h" +#include "html_utils.h" #include "lexcer.h" int main(int argc, char *argv[]) { @@ -13,7 +17,7 @@ int main(int argc, char *argv[]) { return 2; /* unable to open file or inavlid file */ } - auto outputName = LexCer::getOutputFileName(argv[1]); + auto outputName = HTMLUtils::getOutputFileName(argv[1]); auto fpOut = fopen(outputName.c_str(), "w"); if (!fpOut) { return 2; @@ -21,7 +25,7 @@ int main(int argc, char *argv[]) { fputs( - "<!doctype>\n" + "<!DOCTYPE html>\n" "<html>\n" "<head>\n" " <title>LexCed</title>\n" @@ -58,14 +62,51 @@ int main(int argc, char *argv[]) { " .comment {\n" " color: green;\n" " }\n" + " .complexity-level-one {\n" + " background-color: PaleGreen;\n" + " }\n" + " .complexity-level-two {\n" + " background-color: DarkGreen;\n" + " }\n" + " .complexity-level-three {\n" + " background-color: SaddleBrown;\n" + " }\n" + " .complexity-level-four {\n" + " background-color: Brown;\n" + " }\n" + " .complexity-level-five {\n" + " background-color: Maroon;\n" + " }\n" " </style>\n" "</head>\n" - "<body>\n" + "<body onload=\"toggleComplexity()\">\n" "<pre class=\"code\">\n", fpOut ); - LexCer::lexCit(fpIn, fpOut); - fputs("</pre></body></html>\n", fpOut); + ParCer::outputWithCyclomaticComplexity(fpIn, fpOut); + fputs("</pre>\n" + "<script>\n" + "function toggleComplexity() {\n" + " var funcs = document.getElementsByClassName(\"func\");" + " if (funcs.length == 0) return;\n" + " var len = funcs.length;\n" + " for (var i = 0; i < len; ++i) {\n" + " var f = document.getElementsByClassName(\"func\")[0];\n" + " var complexity = f.innerHTML.match(\"(<!-- )([0-9]+)( -->)\")[2];\n" + " if (complexity < 3)\n" + " f.className = \"complexity-level-one\";\n" + " else if (complexity < 7)\n" + " f.className = \"complexity-level-two\";\n" + " else if (complexity < 15)\n" + " f.className = \"complexity-level-three\";\n" + " else if (complexity < 20)\n" + " f.className = \"complexity-level-four\";\n" + " else\n" + " f.className = \"complexity-level-five\";\n" + " }\n" + "}\n", + fpOut); + fputs("</script></body></html>\n", fpOut); printf("Highlighted text written in %s!\n", outputName.c_str()); diff --git a/homework/81568/c2html/test.c b/homework/81568/c2html/test.c index 636032a..0aafa72 100644 --- a/homework/81568/c2html/test.c +++ b/homework/81568/c2html/test.c @@ -69,6 +69,12 @@ void switch_why_not(void) { break; case 'X': printf("why break stuff\n"); + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: default: break; } diff --git a/homework/81568/c2html/test.html b/homework/81568/c2html/test.html index 83b41a5..e39aec0 100644 --- a/homework/81568/c2html/test.html +++ b/homework/81568/c2html/test.html @@ -1,4 +1,4 @@ -<!doctype> +<!DOCTYPE html> <html> <head> <title>LexCed</title> @@ -35,9 +35,24 @@ .comment { color: green; } + .complexity-level-one { + background-color: PaleGreen; + } + .complexity-level-two { + background-color: DarkGreen; + } + .complexity-level-three { + background-color: SaddleBrown; + } + .complexity-level-four { + background-color: Brown; + } + .complexity-level-five { + background-color: Maroon; + } </style> </head> -<body> +<body onload="toggleComplexity()"> <pre class="code"> <span class="preproc">#ifndef</span> <span class="identifier">SAMPLE_CODE_C</span> <span class="preproc">#define</span> <span class="identifier">SAMPLE_CODE_C</span> @@ -46,97 +61,103 @@ <span class="preproc">#include</span> <span class="string"><stdio.h></span> -<span class="typename">int</span> <span class="identifier">bitcount</span>(<span class="typename">long</span> <span class="typename">long</span> <span class="identifier">x</span>) { +<span class="typename">int</span> <span class="identifier">bitcount</span><span class="identifier">(</span><span class="typename">long</span> <span class="typename">long</span> <span class="identifier">x</span><span class="identifier">)</span> <div class="func"><span class="identifier">{</span> <span class="typename">int</span> <span class="identifier">cnt</span> <span class="operator">=</span> <span class="number">0;</span>; - <span class="keyword">while</span> (<span class="identifier">x</span>) { + <span class="keyword">while</span> <span class="identifier">(</span><span class="identifier">x</span><span class="identifier">)</span> <span class="identifier">{</span> <span class="operator">++</span><span class="identifier">cnt</span>; - <span class="identifier">x</span> <span class="operator">&=</span> (<span class="identifier">x</span><span class="operator">-</span><span class="number">1</span>); - } + <span class="identifier">x</span> <span class="operator">&=</span> <span class="identifier">(</span><span class="identifier">x</span><span class="operator">-</span><span class="number">1</span><span class="identifier">)</span>; + <span class="identifier">}</span> <span class="keyword">return</span> <span class="identifier">cnt</span>; -} +<!-- 2 --></div><span class="identifier">}</span> -<span class="typename">void</span> <span class="identifier">shift_to_pos</span>(<span class="typename">int</span> <span class="operator">*</span><span class="identifier">num</span>, <span class="typename">int</span> <span class="identifier">p</span>, <span class="typename">int</span> <span class="identifier">n</span>) { - <span class="operator">*</span><span class="identifier">num</span> <span class="operator">=</span> <span class="identifier">p</span> <span class="operator">></span> <span class="identifier">n</span> <span class="operator">?</span> <span class="operator">*</span><span class="identifier">num</span> <span class="operator"><<</span> (<span class="identifier">p</span> <span class="operator">-</span> <span class="identifier">n</span> <span class="operator">+</span> <span class="number">1</span>) <span class="operator">:</span> <span class="operator">*</span><span class="identifier">num</span> <span class="operator">>></span> (<span class="identifier">n</span> <span class="operator">-</span> <span class="identifier">p</span> <span class="operator">+</span> <span class="number">1</span>); -} +<span class="typename">void</span> <span class="identifier">shift_to_pos</span><span class="identifier">(</span><span class="typename">int</span> <span class="operator">*</span><span class="identifier">num</span>, <span class="typename">int</span> <span class="identifier">p</span>, <span class="typename">int</span> <span class="identifier">n</span><span class="identifier">)</span> <div class="func"><span class="identifier">{</span> + <span class="operator">*</span><span class="identifier">num</span> <span class="operator">=</span> <span class="identifier">p</span> <span class="operator">></span> <span class="identifier">n</span> <span class="operator">?</span> <span class="operator">*</span><span class="identifier">num</span> <span class="operator"><<</span> <span class="identifier">(</span><span class="identifier">p</span> <span class="operator">-</span> <span class="identifier">n</span> <span class="operator">+</span> <span class="number">1</span><span class="identifier">)</span> <span class="operator">:</span> <span class="operator">*</span><span class="identifier">num</span> <span class="operator">>></span> <span class="identifier">(</span><span class="identifier">n</span> <span class="operator">-</span> <span class="identifier">p</span> <span class="operator">+</span> <span class="number">1</span><span class="identifier">)</span>; +<!-- 1 --></div><span class="identifier">}</span> -<span class="typename">int</span> <span class="identifier">setbits</span>(<span class="identifier">x</span>, <span class="identifier">p</span>, <span class="identifier">n</span>, <span class="identifier">y</span>) { - <span class="typename">int</span> <span class="identifier">mask</span> <span class="operator">=</span> (<span class="number">1</span> <span class="operator"><<</span> <span class="identifier">n</span>) <span class="operator">-</span> <span class="number">1</span>; +<span class="typename">int</span> <span class="identifier">setbits</span><span class="identifier">(</span><span class="identifier">x</span>, <span class="identifier">p</span>, <span class="identifier">n</span>, <span class="identifier">y</span><span class="identifier">)</span> <div class="func"><span class="identifier">{</span> + <span class="typename">int</span> <span class="identifier">mask</span> <span class="operator">=</span> <span class="identifier">(</span><span class="number">1</span> <span class="operator"><<</span> <span class="identifier">n</span><span class="identifier">)</span> <span class="operator">-</span> <span class="number">1</span>; <span class="typename">int</span> <span class="identifier">to_set</span> <span class="operator">=</span> <span class="identifier">y</span> <span class="operator">&</span> <span class="identifier">mask</span>; - <span class="identifier">shift_to_pos</span>(<span class="operator">&</span><span class="identifier">mask</span>, <span class="identifier">p</span>, <span class="identifier">n</span>); - <span class="identifier">shift_to_pos</span>(<span class="operator">&</span><span class="identifier">to_set</span>, <span class="identifier">p</span>, <span class="identifier">n</span>); - <span class="keyword">return</span> (<span class="identifier">x</span> <span class="operator">&</span> <span class="operator">~</span><span class="identifier">mask</span>) <span class="operator">|</span> <span class="identifier">to_set</span>; -} + <span class="identifier">shift_to_pos</span><span class="identifier">(</span><span class="operator">&</span><span class="identifier">mask</span>, <span class="identifier">p</span>, <span class="identifier">n</span><span class="identifier">)</span>; + <span class="identifier">shift_to_pos</span><span class="identifier">(</span><span class="operator">&</span><span class="identifier">to_set</span>, <span class="identifier">p</span>, <span class="identifier">n</span><span class="identifier">)</span>; + <span class="keyword">return</span> <span class="identifier">(</span><span class="identifier">x</span> <span class="operator">&</span> <span class="operator">~</span><span class="identifier">mask</span><span class="identifier">)</span> <span class="operator">|</span> <span class="identifier">to_set</span>; +<!-- 1 --></div><span class="identifier">}</span> -<span class="typename">unsigned</span> <span class="identifier">invert</span>(<span class="typename">unsigned</span> <span class="identifier">x</span>, <span class="typename">unsigned</span> <span class="identifier">p</span>, <span class="typename">unsigned</span> <span class="identifier">n</span>) { +<span class="typename">unsigned</span> <span class="identifier">invert</span><span class="identifier">(</span><span class="typename">unsigned</span> <span class="identifier">x</span>, <span class="typename">unsigned</span> <span class="identifier">p</span>, <span class="typename">unsigned</span> <span class="identifier">n</span><span class="identifier">)</span> <div class="func"><span class="identifier">{</span> <span class="operator">++</span><span class="identifier">p</span>; <span class="comment">// in case p < n</span> - <span class="keyword">while</span>(<span class="identifier">n</span><span class="operator">--</span> <span class="operator">&&</span> <span class="identifier">p</span><span class="operator">--</span>) { - <span class="keyword">if</span> (<span class="operator">!</span>(<span class="identifier">x</span> <span class="operator">&</span> (<span class="number">1</span> <span class="operator"><<</span> <span class="identifier">n</span>))) { - <span class="identifier">x</span> <span class="operator">|=</span> (<span class="number">1</span> <span class="operator"><<</span> <span class="identifier">n</span>); - } <span class="keyword">else</span> { - <span class="identifier">x</span> <span class="operator">^=</span> (<span class="number">1</span> <span class="operator"><<</span> <span class="identifier">n</span>); - } - } + <span class="keyword">while</span><span class="identifier">(</span><span class="identifier">n</span><span class="operator">--</span> <span class="operator">&&</span> <span class="identifier">p</span><span class="operator">--</span><span class="identifier">)</span> <span class="identifier">{</span> + <span class="keyword">if</span> <span class="identifier">(</span><span class="operator">!</span><span class="identifier">(</span><span class="identifier">x</span> <span class="operator">&</span> <span class="identifier">(</span><span class="number">1</span> <span class="operator"><<</span> <span class="identifier">n</span><span class="identifier">)</span><span class="identifier">)</span><span class="identifier">)</span> <span class="identifier">{</span> + <span class="identifier">x</span> <span class="operator">|=</span> <span class="identifier">(</span><span class="number">1</span> <span class="operator"><<</span> <span class="identifier">n</span><span class="identifier">)</span>; + <span class="identifier">}</span> <span class="keyword">else</span> <span class="identifier">{</span> + <span class="identifier">x</span> <span class="operator">^=</span> <span class="identifier">(</span><span class="number">1</span> <span class="operator"><<</span> <span class="identifier">n</span><span class="identifier">)</span>; + <span class="identifier">}</span> + <span class="identifier">}</span> <span class="keyword">return</span> <span class="identifier">x</span>; -} +<!-- 3 --></div><span class="identifier">}</span> -<span class="typename">int</span> <span class="identifier">rightrot</span>(<span class="typename">long</span> <span class="typename">long</span> <span class="identifier">x</span>, <span class="typename">int</span> <span class="identifier">n</span>) { - <span class="typename">int</span> <span class="identifier">bitcnt</span> <span class="operator">=</span> <span class="identifier">bitcount</span>(<span class="identifier">x</span>); +<span class="typename">int</span> <span class="identifier">rightrot</span><span class="identifier">(</span><span class="typename">long</span> <span class="typename">long</span> <span class="identifier">x</span>, <span class="typename">int</span> <span class="identifier">n</span><span class="identifier">)</span> <div class="func"><span class="identifier">{</span> + <span class="typename">int</span> <span class="identifier">bitcnt</span> <span class="operator">=</span> <span class="identifier">bitcount</span><span class="identifier">(</span><span class="identifier">x</span><span class="identifier">)</span>; <span class="identifier">x</span> <span class="operator"><<=</span> <span class="identifier">n</span>; - <span class="keyword">return</span> (<span class="identifier">x</span> <span class="operator">&</span> ( (<span class="number">1</span> <span class="operator"><<</span> (<span class="identifier">bitcnt</span>)) <span class="operator">-</span> <span class="number">1</span>) ) <span class="operator">|</span> (<span class="identifier">x</span> <span class="operator">&</span> <span class="operator">~</span>( (<span class="number">1</span> <span class="operator"><<</span> <span class="identifier">bitcnt</span>) <span class="operator">-</span> <span class="number">1</span> )) <span class="operator">>></span> <span class="identifier">bitcnt</span>; -} + <span class="keyword">return</span> <span class="identifier">(</span><span class="identifier">x</span> <span class="operator">&</span> <span class="identifier">(</span> <span class="identifier">(</span><span class="number">1</span> <span class="operator"><<</span> <span class="identifier">(</span><span class="identifier">bitcnt</span><span class="identifier">)</span><span class="identifier">)</span> <span class="operator">-</span> <span class="number">1</span><span class="identifier">)</span> <span class="identifier">)</span> <span class="operator">|</span> <span class="identifier">(</span><span class="identifier">x</span> <span class="operator">&</span> <span class="operator">~</span><span class="identifier">(</span> <span class="identifier">(</span><span class="number">1</span> <span class="operator"><<</span> <span class="identifier">bitcnt</span><span class="identifier">)</span> <span class="operator">-</span> <span class="number">1</span> <span class="identifier">)</span><span class="identifier">)</span> <span class="operator">>></span> <span class="identifier">bitcnt</span>; +<!-- 1 --></div><span class="identifier">}</span> <span class="typename">char</span> <span class="identifier">num</span><span class="operator">[</span><span class="number">32</span><span class="operator">]</span>; -<span class="typename">void</span> <span class="identifier">to_binary</span>(<span class="typename">unsigned</span> <span class="identifier">x</span>) { +<span class="typename">void</span> <span class="identifier">to_binary</span><span class="identifier">(</span><span class="typename">unsigned</span> <span class="identifier">x</span><span class="identifier">)</span> <div class="func"><span class="identifier">{</span> <span class="typename">int</span> <span class="identifier">i</span> <span class="operator">=</span> <span class="number">31</span>; <span class="identifier">num</span><span class="operator">[</span><span class="number">32</span><span class="operator">]</span> <span class="operator">=</span> <span class="string">'\0'</span>; - <span class="keyword">while</span> (<span class="identifier">x</span>) { - <span class="keyword">if</span> (<span class="identifier">x</span> <span class="operator">&</span> <span class="number">1</span>) <span class="identifier">num</span><span class="operator">[</span><span class="identifier">i</span><span class="operator">]</span> <span class="operator">=</span> <span class="string">'1'</span>; + <span class="keyword">while</span> <span class="identifier">(</span><span class="identifier">x</span><span class="identifier">)</span> <span class="identifier">{</span> + <span class="keyword">if</span> <span class="identifier">(</span><span class="identifier">x</span> <span class="operator">&</span> <span class="number">1</span><span class="identifier">)</span> <span class="identifier">num</span><span class="operator">[</span><span class="identifier">i</span><span class="operator">]</span> <span class="operator">=</span> <span class="string">'1'</span>; <span class="keyword">else</span> <span class="identifier">num</span><span class="operator">[</span><span class="identifier">i</span><span class="operator">]</span> <span class="operator">=</span> <span class="string">'0'</span>; <span class="operator">--</span><span class="identifier">i</span>; <span class="identifier">x</span> <span class="operator">>>=</span> <span class="number">1</span>; - } - <span class="keyword">for</span> (; <span class="identifier">i</span> <span class="operator">></span><span class="operator">=</span> <span class="number">0;</span>; <span class="operator">--</span><span class="identifier">i</span>) <span class="identifier">num</span><span class="operator">[</span><span class="identifier">i</span><span class="operator">]</span> <span class="operator">=</span> <span class="string">'0'</span>; - <span class="keyword">for</span> (; <span class="identifier">i</span> <span class="operator"><</span> <span class="number">32</span>; <span class="operator">++</span><span class="identifier">i</span>) { - <span class="identifier">printf</span>(<span class="string">"%c%s"</span>, <span class="identifier">num</span><span class="operator">[</span><span class="identifier">i</span><span class="operator">]</span>, <span class="operator">!</span>((<span class="identifier">i</span><span class="operator">+</span><span class="number">1</span>) <span class="operator">%</span> <span class="number">4</span>) <span class="operator">?</span> <span class="string">" "</span> <span class="operator">:</span> <span class="string">""</span>); - } -} + <span class="identifier">}</span> + <span class="keyword">for</span> <span class="identifier">(</span>; <span class="identifier">i</span> <span class="operator">></span><span class="operator">=</span> <span class="number">0;</span>; <span class="operator">--</span><span class="identifier">i</span><span class="identifier">)</span> <span class="identifier">num</span><span class="operator">[</span><span class="identifier">i</span><span class="operator">]</span> <span class="operator">=</span> <span class="string">'0'</span>; + <span class="keyword">for</span> <span class="identifier">(</span>; <span class="identifier">i</span> <span class="operator"><</span> <span class="number">32</span>; <span class="operator">++</span><span class="identifier">i</span><span class="identifier">)</span> <span class="identifier">{</span> + <span class="identifier">printf</span><span class="identifier">(</span><span class="string">"%c%s"</span>, <span class="identifier">num</span><span class="operator">[</span><span class="identifier">i</span><span class="operator">]</span>, <span class="operator">!</span><span class="identifier">(</span><span class="identifier">(</span><span class="identifier">i</span><span class="operator">+</span><span class="number">1</span><span class="identifier">)</span> <span class="operator">%</span> <span class="number">4</span><span class="identifier">)</span> <span class="operator">?</span> <span class="string">" "</span> <span class="operator">:</span> <span class="string">""</span><span class="identifier">)</span>; + <span class="identifier">}</span> +<!-- 5 --></div><span class="identifier">}</span> -<span class="typename">void</span> <span class="identifier">switch_why_not</span>(<span class="typename">void</span>) { +<span class="typename">void</span> <span class="identifier">switch_why_not</span><span class="identifier">(</span><span class="typename">void</span><span class="identifier">)</span> <div class="func"><span class="identifier">{</span> <span class="typename">char</span> <span class="identifier">c</span> <span class="operator">=</span> <span class="string">'X'</span>; - <span class="keyword">switch</span>(<span class="identifier">c</span>) { + <span class="keyword">switch</span><span class="identifier">(</span><span class="identifier">c</span><span class="identifier">)</span> <span class="identifier">{</span> <span class="keyword">case</span> <span class="string">'x'</span><span class="operator">:</span> - <span class="identifier">printf</span>(<span class="string">"hex\n"</span>); + <span class="identifier">printf</span><span class="identifier">(</span><span class="string">"hex\n"</span><span class="identifier">)</span>; <span class="keyword">break</span>; <span class="keyword">case</span> <span class="string">'X'</span><span class="operator">:</span> - <span class="identifier">printf</span>(<span class="string">"why break stuff\n"</span>); + <span class="identifier">printf</span><span class="identifier">(</span><span class="string">"why break stuff\n"</span><span class="identifier">)</span>; + <span class="keyword">case</span> <span class="number">1</span><span class="operator">:</span> + <span class="keyword">case</span> <span class="number">2</span><span class="operator">:</span> + <span class="keyword">case</span> <span class="number">3</span><span class="operator">:</span> + <span class="keyword">case</span> <span class="number">4</span><span class="operator">:</span> + <span class="keyword">case</span> <span class="number">5</span><span class="operator">:</span> + <span class="keyword">case</span> <span class="number">6</span><span class="operator">:</span> <span class="keyword">default</span><span class="operator">:</span> <span class="keyword">break</span>; - } + <span class="identifier">}</span> <span class="keyword">return</span>; -} +<!-- 10 --></div><span class="identifier">}</span> -<span class="identifier">main</span>() { +<span class="identifier">main</span><span class="identifier">(</span><span class="identifier">)</span> <div class="func"><span class="identifier">{</span> <span class="typename">long</span> <span class="typename">long</span> <span class="identifier">x</span> <span class="operator">=</span> <span class="number">0b110110</span>; - <span class="identifier">printf</span>(<span class="string">"rightrot:\n"</span>); - <span class="identifier">to_binary</span>(<span class="identifier">x</span>); - <span class="identifier">printf</span>(<span class="string">"\n"</span>); - <span class="identifier">to_binary</span>(<span class="identifier">rightrot</span>(<span class="identifier">x</span>, <span class="number">3</span>)); - <span class="identifier">printf</span>(<span class="string">"\n"</span>); + <span class="identifier">printf</span><span class="identifier">(</span><span class="string">"rightrot:\n"</span><span class="identifier">)</span>; + <span class="identifier">to_binary</span><span class="identifier">(</span><span class="identifier">x</span><span class="identifier">)</span>; + <span class="identifier">printf</span><span class="identifier">(</span><span class="string">"\n"</span><span class="identifier">)</span>; + <span class="identifier">to_binary</span><span class="identifier">(</span><span class="identifier">rightrot</span><span class="identifier">(</span><span class="identifier">x</span>, <span class="number">3</span><span class="identifier">)</span><span class="identifier">)</span>; + <span class="identifier">printf</span><span class="identifier">(</span><span class="string">"\n"</span><span class="identifier">)</span>; <span class="typename">unsigned</span> <span class="identifier">i</span> <span class="operator">=</span> <span class="number">0b101010</span>; - <span class="identifier">printf</span>(<span class="string">"invert:\n"</span>); - <span class="identifier">to_binary</span>(<span class="identifier">i</span>); - <span class="identifier">printf</span>(<span class="string">"\n"</span>); - <span class="identifier">to_binary</span>(<span class="identifier">invert</span>(<span class="identifier">i</span>, <span class="number">4</span>, <span class="number">4</span>)); - <span class="identifier">printf</span>(<span class="string">"\n"</span>); + <span class="identifier">printf</span><span class="identifier">(</span><span class="string">"invert:\n"</span><span class="identifier">)</span>; + <span class="identifier">to_binary</span><span class="identifier">(</span><span class="identifier">i</span><span class="identifier">)</span>; + <span class="identifier">printf</span><span class="identifier">(</span><span class="string">"\n"</span><span class="identifier">)</span>; + <span class="identifier">to_binary</span><span class="identifier">(</span><span class="identifier">invert</span><span class="identifier">(</span><span class="identifier">i</span>, <span class="number">4</span>, <span class="number">4</span><span class="identifier">)</span><span class="identifier">)</span>; + <span class="identifier">printf</span><span class="identifier">(</span><span class="string">"\n"</span><span class="identifier">)</span>; <span class="typename">long</span> <span class="typename">long</span> <span class="identifier">a</span> <span class="operator">=</span> <span class="number">0b111001010011</span>; <span class="typename">long</span> <span class="typename">long</span> <span class="identifier">b</span> <span class="operator">=</span> <span class="number">0b11111010</span>; - <span class="identifier">printf</span>(<span class="string">"bits of: "</span>); <span class="identifier">to_binary</span>(<span class="identifier">a</span>); <span class="identifier">printf</span>(<span class="string">"\n"</span>); - <span class="identifier">printf</span>(<span class="string">"bits to: "</span>); <span class="identifier">to_binary</span>(<span class="identifier">b</span>); <span class="identifier">printf</span>(<span class="string">"\n"</span>); - <span class="identifier">to_binary</span>(<span class="identifier">setbits</span>(<span class="identifier">a</span>, <span class="number">6</span>, <span class="number">4</span>, <span class="identifier">b</span>)); + <span class="identifier">printf</span><span class="identifier">(</span><span class="string">"bits of: "</span><span class="identifier">)</span>; <span class="identifier">to_binary</span><span class="identifier">(</span><span class="identifier">a</span><span class="identifier">)</span>; <span class="identifier">printf</span><span class="identifier">(</span><span class="string">"\n"</span><span class="identifier">)</span>; + <span class="identifier">printf</span><span class="identifier">(</span><span class="string">"bits to: "</span><span class="identifier">)</span>; <span class="identifier">to_binary</span><span class="identifier">(</span><span class="identifier">b</span><span class="identifier">)</span>; <span class="identifier">printf</span><span class="identifier">(</span><span class="string">"\n"</span><span class="identifier">)</span>; + <span class="identifier">to_binary</span><span class="identifier">(</span><span class="identifier">setbits</span><span class="identifier">(</span><span class="identifier">a</span>, <span class="number">6</span>, <span class="number">4</span>, <span class="identifier">b</span><span class="identifier">)</span><span class="identifier">)</span>; <span class="typename">int</span> <span class="identifier">testInt</span> <span class="operator">=</span> <span class="number">12345678</span>; @@ -144,8 +165,28 @@ <span class="typename">double</span> <span class="identifier">testDouble</span> <span class="operator">=</span> <span class="number">1234.5678</span>; <span class="keyword">return</span> <span class="number">0;</span>; -} +<!-- 1 --></div><span class="identifier">}</span> <span class="preproc">#endif</span> <span class="comment">/* SAMPLE_CODE_C */</span> -</pre></body></html> +</pre> +<script> +function toggleComplexity() { + var funcs = document.getElementsByClassName("func"); if (funcs.length == 0) return; + var len = funcs.length; + for (var i = 0; i < len; ++i) { + var f = document.getElementsByClassName("func")[0]; + var complexity = f.innerHTML.match("(<!-- )([0-9]+)( -->)")[2]; + if (complexity < 3) + f.className = "complexity-level-one"; + else if (complexity < 7) + f.className = "complexity-level-two"; + else if (complexity < 15) + f.className = "complexity-level-three"; + else if (complexity < 20) + f.className = "complexity-level-four"; + else + f.className = "complexity-level-five"; + } +} +</script></body></html> |
