Added comments in Syntaxhighlighter + small fix in attributelexer regex

This commit is contained in:
Thomas Ave 2016-05-29 01:35:39 +02:00
parent f87ce737fc
commit 1858126b13
3 changed files with 48 additions and 13 deletions

View File

@ -11,16 +11,33 @@
class Highlighter { class Highlighter {
public: public:
/**
* Create a new Highlighter with the content of the xml file
*/
Highlighter(std::istream &file); Highlighter(std::istream &file);
virtual ~Highlighter(); virtual ~Highlighter();
/**
* Do the actual highlighting and write it to the provided ostream
* This is a pure virtual function and has to be implemented when creating a new kind of highlighter
*/
virtual void highlight(std::ostream &os)=0; virtual void highlight(std::ostream &os)=0;
protected: protected:
/**
* Do the actual work with the lexer
*/
void process(); void process();
/**
* Local Tokentype used to identify what part of the xml structure is inside the token
* This is necessary because we use two different lexers with different TokenTypes
*/
enum TokenType { enum TokenType {
COMMENT, COMMENT,
TAG, TAG,
@ -32,20 +49,38 @@ class Highlighter {
BRACKET, BRACKET,
nonmatching nonmatching
}; };
/**
* Represent all the different colors
*/
enum Color { Red, Green, Blue, Orange, Yellow, Cyan, Grey, Black, White, Magenta, Pink, Brown, Indigo, Violet, Undefined}; // All the colors, not all of them are used, but it's easy to change now enum Color { Red, Green, Blue, Orange, Yellow, Cyan, Grey, Black, White, Magenta, Pink, Brown, Indigo, Violet, Undefined}; // All the colors, not all of them are used, but it's easy to change now
/**
* A structure used to hold the tokens with their content, TokenType and color
*/
struct Token { struct Token {
std::string content = ""; std::string content = "";
Color color; Color color;
TokenType type; TokenType type;
}; };
// Used to determine the color connected to the TokenType
std::map<TokenType, Color> colormap; std::map<TokenType, Color> colormap;
// Hold the tokens
std::vector<Token> m_tokens; std::vector<Token> m_tokens;
// Hold the first lexer
XMLLexer *m_lexer; XMLLexer *m_lexer;
}; };
class ConsoleHighlighter: public Highlighter { class ConsoleHighlighter: public Highlighter {
/**
* A SyntaxHighlighter specifically for console output
* Look at the base class for more information
*/
public: public:
ConsoleHighlighter(std::istream &file); ConsoleHighlighter(std::istream &file);
void highlight(std::ostream &os); void highlight(std::ostream &os);

View File

@ -1,6 +1,6 @@
ELEMENT = </?[ ]*[a-zA-Z0-9-]* ELEMENT = </?[ ]*[a-zA-Z0-9-]*
WHITESPACE = [ ]* WHITESPACE = [ ]*
ATTRIBUTE = [a-zA-Z0-9-]*[ ]*= ATTRIBUTE = [a-zA-Z0-9-]*[ ]*=?
ATTRIBUTE_CONTENT_DOUBLE_QUOTES = "[^<>"]*" ATTRIBUTE_CONTENT_DOUBLE_QUOTES = "[^<>"]*"
ATTRIBUTE_CONTENT_SINGLE_QUOTES = '[^<>']*' ATTRIBUTE_CONTENT_SINGLE_QUOTES = '[^<>']*'
BRACKET = [</>] BRACKET = [</>]

View File

@ -5,7 +5,7 @@
Highlighter::Highlighter(std::istream &file) { Highlighter::Highlighter(std::istream &file) {
m_lexer = new XMLLexer(file); m_lexer = new XMLLexer(file);
colormap[CONTENT] = Undefined; colormap[CONTENT] = Undefined; // The abstract base class shouldn't have default colors
colormap[ELEMENT] = Undefined; colormap[ELEMENT] = Undefined;
colormap[ATTRIBUTE] = Undefined; colormap[ATTRIBUTE] = Undefined;
colormap[ATTRIBURE_CONTENT] = Undefined; colormap[ATTRIBURE_CONTENT] = Undefined;
@ -19,12 +19,12 @@ Highlighter::~Highlighter() {
} }
void Highlighter::process() { void Highlighter::process() {
while (true) { while (true) { // Wait until the NoMoreTokens exception is thrown
try { try {
XMLLexer::Token token = m_lexer->nextToken(); XMLLexer::Token token = m_lexer->nextToken(); // Get the next token
Token newtoken; Token newtoken;
newtoken.content = token.content; newtoken.content = token.content;
switch(token.type) { switch(token.type) { // setup local tokentype
case XMLLexer::TokenType::CONTENT: case XMLLexer::TokenType::CONTENT:
newtoken.type = CONTENT; newtoken.type = CONTENT;
break; break;
@ -38,11 +38,11 @@ void Highlighter::process() {
newtoken.type = nonmatching; newtoken.type = nonmatching;
break; break;
} }
newtoken.color = colormap.find(newtoken.type)->second; newtoken.color = colormap.find(newtoken.type)->second; // get the appropriate color
m_tokens.push_back(newtoken); m_tokens.push_back(newtoken);
} catch (XMLLexer::NoMoreTokens &err) { } catch (XMLLexer::NoMoreTokens &err) {
break; break; // We reached the end of the file
} catch (XMLLexer::NoMatch& err) { } catch (XMLLexer::NoMatch& err) { // No match was found, setup a new token with 1 character and tokentype nonmatching + skip this character
Token newtoken; Token newtoken;
newtoken.content = m_lexer->peek(); newtoken.content = m_lexer->peek();
m_lexer->skip(1); m_lexer->skip(1);
@ -53,7 +53,7 @@ void Highlighter::process() {
auto tokens = std::move(m_tokens); auto tokens = std::move(m_tokens);
m_tokens.clear(); m_tokens.clear();
for(auto &tagtoken: tokens) { for(auto &tagtoken: tokens) {
if(tagtoken.type == TAG && !tagtoken.content.empty()) { if(tagtoken.type == TAG && !tagtoken.content.empty()) { // If the token was a tag, use a second lexer to find attributes etc.
std::istringstream content(tagtoken.content); std::istringstream content(tagtoken.content);
AttributeLexer attributelexer(content); AttributeLexer attributelexer(content);
while (true) { while (true) {
@ -100,8 +100,8 @@ void Highlighter::process() {
} }
ConsoleHighlighter::ConsoleHighlighter(std::istream &file): Highlighter(file) { ConsoleHighlighter::ConsoleHighlighter(std::istream &file): Highlighter(file) {
colormap[CONTENT] = White; colormap[CONTENT] = White; // Fill in the colors we want to use for each tokentype
colormap[ELEMENT] = Blue; colormap[ELEMENT] = Blue; // Change these for different colors
colormap[TAG] = Magenta; colormap[TAG] = Magenta;
colormap[ATTRIBUTE] = Yellow; colormap[ATTRIBUTE] = Yellow;
colormap[ATTRIBURE_CONTENT] = Green; colormap[ATTRIBURE_CONTENT] = Green;
@ -112,7 +112,7 @@ ConsoleHighlighter::ConsoleHighlighter(std::istream &file): Highlighter(file) {
} }
void ConsoleHighlighter::highlight(std::ostream &os) { void ConsoleHighlighter::highlight(std::ostream &os) {
for(auto &token: m_tokens) { for(auto &token: m_tokens) { // Go over all tokens and print them out with the right color
switch(token.color) { switch(token.color) {
case Yellow: case Yellow:
os << "\033[1;33m" << token.content << "\033[0m"; os << "\033[1;33m" << token.content << "\033[0m";