-
Notifications
You must be signed in to change notification settings - Fork 0
/
Viz.h
164 lines (135 loc) · 4.69 KB
/
Viz.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
//
// Created by nisal on 7/20/2023.
//
#ifndef RPAL_FINAL_VIZ_H
#define RPAL_FINAL_VIZ_H
//
// Created by nisal on 7/19/2023.
//
#include <iostream>
#include <unordered_map>
#include <fstream>
#include "Token.h"
#include "TreeNode.h"
// Map the enum values to their string representations
std::unordered_map<token_type, std::string> token_typeNames = {
{token_type::IDENTIFIER, "IDENTIFIER"},
{token_type::INTEGER, "INTEGER"},
{token_type::STRING, "STRING"},
{token_type::OPERATOR, "OPERATOR"},
{token_type::DELIMITER, "DELIMITER"},
{token_type::KEYWORD, "KEYWORD"},
{token_type::END_OF_FILE, "END_OF_FILE"}};
// Function to get the string representation of the token_type
[[maybe_unused]] std::string gettoken_typeName(token_type type)
{
if (token_typeNames.count(type) > 0)
{
return token_typeNames[type];
}
return "UNKNOWN";
}
// Function to check if Graphviz is installed
bool isGraphvizInstalled()
{
// Redirect stderr to /dev/null or nul to discard error message
#ifdef _WIN32
const char *redirectCommand = "2>nul";
#else
const char *redirectCommand = "2>/dev/null";
#endif
std::string command = "dot -V ";
command += redirectCommand;
int exitCode = system(command.c_str());
return (exitCode == 0);
}
// Function to print a warning message in yellow color with download link to Graphviz
void printYellowWarning(const std::string &message)
{
std::cout << "\033[1;33m" << message << "\033[0m";
}
// Function to print the warning message if Graphviz is not installed
void printGraphvizWarning()
{
std::string warningMessage = "WARNING: Graphviz is not installed on this computer.";
warningMessage += " Download Graphviz from: ";
printYellowWarning(warningMessage);
std::cout << "https://graphviz.org/download/\n"
<< std::endl;
}
/**
* Helper function to generate the dot file contents recursively.
*
* @param node The current TreeNode being processed.
* @param file The ofstream object for writing the dot file.
* @param parent The parent node ID (default: -1).
* @return The ID of the current node.
*/
// NOLINTNEXTLINE
int generateDotFileHelper(TreeNode *node, std::ofstream &file, int parent = -1, int nodeCount = 0)
{
int currentNode = nodeCount;
// Increment nodeCount for the next call
int nextNodeCount = nodeCount + 1;
// Determine colors and fill based on node values
std::string labelColor = "darkblue";
std::string valueColor = "darkgreen";
std::string fillColor = (node->getValue() == " " || node->getValue().empty()) ? "#CCCCCC" : "#FFFFFF";
// Escape label characters if necessary
std::string escapedLabel = node->getLabel();
size_t pos1 = escapedLabel.find('&');
while (pos1 != std::string::npos)
{
escapedLabel.replace(pos1, 1, "&");
pos1 = escapedLabel.find('&', pos1 + 5); // Move to the next occurrence after the replaced token
}
size_t pos = escapedLabel.find('>');
while (pos != std::string::npos)
{
escapedLabel.replace(pos, 1, ">");
pos = escapedLabel.find('>', pos + 4);
}
// Prepare label and value strings for the dot file
std::string labelStr = (escapedLabel.empty()) ? " " : escapedLabel;
std::string valueStr = (node->getValue().empty()) ? " " : node->getValue();
size_t pos2 = valueStr.find('\n');
while (pos2 != std::string::npos)
{
valueStr.replace(pos2, 1, "\\n");
pos2 = valueStr.find('\n', pos2 + 2);
}
// Write the node details to the dot file
file << " node" << currentNode << " [label=<";
file << "<font color=\"" << labelColor << "\">" << labelStr << "</font><br/>";
file << "<font color=\"" << valueColor << "\">" << valueStr << "</font>";
file << ">, style=filled, fillcolor=\"" << fillColor << "\"];\n";
// Connect the current node to its parent (if not the root)
if (currentNode != 0 && parent != -1)
{
file << " node" << parent << " -> node" << currentNode << ";\n";
}
// Recursively generate dot file contents for each child node
for (TreeNode *child : node->getChildren())
{
nextNodeCount = generateDotFileHelper(child, file, currentNode, nextNodeCount);
}
return nextNodeCount;
}
/**
* Generates a dot file representing the AST.
*
* @param root The root node of the AST.
*/
void generateDotFile(TreeNode *root, const std::string& filename)
{
std::string f_name = std::string("Visualizations\\") + filename;
std::ofstream file(f_name);
if (file.is_open())
{
file << "digraph Tree {\n";
generateDotFileHelper(root, file, 0);
file << "}\n";
file.close();
}
}
#endif //RPAL_FINAL_VIZ_H