Commit 9a8591bd authored by aggsol's avatar aggsol

basic graph generation

parent e09e8b00
digraph G {
1 [shape=box];
7 [peripheries=2];
1 -> 2;
1 -> 3;
2 -> 4;
2 -> 6;
4 -> 5;
5 -> 7;
}
\ No newline at end of file
7 [peripheries=2];
}
......@@ -64,4 +64,4 @@ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
*YOU DIED!*
[[section-7]]
== 7
\ No newline at end of file
== 7
......@@ -6,6 +6,7 @@
#include <sstream>
#include <deque>
#include <map>
#include <set>
namespace {
const std::string SECTION_SUFFIX = "section-";
......@@ -18,8 +19,8 @@ public:
int m_startLine = -1;
std::deque<std::string> m_lines;
std::deque<int> m_parents;
std::deque<int> m_children;
// std::deque<int> m_parents;
std::set<int> m_children;
std::string m_style;
};
......@@ -35,13 +36,17 @@ private:
int m_currSection = -1;
std::map<int, Section> m_sections;
enum class LineState
enum class State
{
Done = -1,
Start = 0,
CommentStart = 1,
DataStart = 2,
SectionTitle = 3,
Style = 4,
ReferenceStart = 5,
ReferenceSection = 6,
ReferenceEnd = 7
};
};
......@@ -52,43 +57,80 @@ void Parser::parseLine(const std::string& line)
return;
}
LineState state = LineState::Start;
bool done = false;
State state = State::Start;
std::string value;
for(unsigned i=0; i<line.size() && not done; ++i)
for(unsigned i=0; i<line.size() && state != State::Done; ++i)
{
char c = line[i];
switch(state)
{
case LineState::Start:
case State::Start:
if(c == '/')
{
state = LineState::CommentStart;
state = State::CommentStart;
}
else if(c == '[')
{
state = LineState::DataStart;
state = State::DataStart;
}
else if(c == '=')
else if(c == '=')
{
state = LineState::SectionTitle;
state = State::SectionTitle;
}
else if(c == '<')
{
state = State::ReferenceStart;
}
break;
case State::ReferenceStart:
if(c == '<')
{
state = State::ReferenceSection;
}
else
{
value.clear();
state = State::Start;
}
break;
case State::ReferenceSection:
if(c == '>')
{
int section = std::stoi(value);
m_sections[m_currSection].m_children.insert(section);
state = State::ReferenceEnd;
}
else if(std::isdigit(c))
{
value += c;
}
break;
case State::ReferenceEnd:
if(c == '>')
{
state = State::Start;
}
else
{
throw std::runtime_error("Expected '>'");
}
break;
case LineState::Style:
case State::Style:
if(c == '\n' || c == ' ' || c == '\t' || c == '\r')
{
throw std::runtime_error("Invalid style/class");
}
else if(c == ']')
{
done = true;
state = State::Done;
}
else
{
m_sections[m_currSection].m_style += c;
}
break;
case LineState::SectionTitle:
case State::SectionTitle:
if(c == '=')
{
// NOP
......@@ -102,7 +144,7 @@ void Parser::parseLine(const std::string& line)
{
throw std::runtime_error("Mismatch section title and section anchor");
}
done = true;
state = State::Done;
}
catch(const std::exception& ex)
{
......@@ -115,10 +157,10 @@ void Parser::parseLine(const std::string& line)
}
}
break;
case LineState::DataStart:
case State::DataStart:
if(c == '.')
{
state = LineState::Style;
state = State::Style;
m_sections[m_currSection].m_style += c;
}
else if(c == '[')
......@@ -141,7 +183,7 @@ void Parser::parseLine(const std::string& line)
m_sections[section].m_number = section;
m_currSection = section;
done = true;
state = State::Done;
}
catch(const std::exception& ex)
{
......@@ -154,14 +196,14 @@ void Parser::parseLine(const std::string& line)
throw std::runtime_error("Invalid attribute. Missing '[' or '.'");
}
break;
case LineState::CommentStart:
case State::CommentStart:
if(c != '/')
{
throw std::runtime_error("Invalid comment. Missing /");
}
else
{
done = true;
state = State::Done;
}
break;
default:
......@@ -180,10 +222,11 @@ void Parser::parseLine(const std::string& line)
int main(int argc, char* argv[])
{
bodhi::CliArguments args(argc, argv);
auto version = args.getOpt("", "version");
auto help = args.getOpt("h", "help");
// auto version = args.getOpt("", "version");
// auto help = args.getOpt("h", "help");
auto input = args.getOpt<std::string>("i", "input", "<missing input file>");
auto dot = args.getOpt("d", "dot");
std::ifstream file(input);
if(not file.is_open())
......@@ -212,5 +255,37 @@ int main(int argc, char* argv[])
std::cout << "Line count: " << lineCounter << "\n"
<< "Number of sections: " << parser.sections().size() << "\n";
for(auto& s: parser.sections())
{
std::cout << "number:" << s.second.m_number
<< " style: " << s.second.m_style << "\n"
<< "-> Number of children: " << s.second.m_children.size() << "\n";
}
if(dot)
{
std::ofstream dotfile("graph.dot");
if(not dotfile.is_open())
{
throw std::runtime_error("Cannot write dot file");
}
dotfile << "digraph G {\n"
<< " node [style=filled fillcolor=white];";
for(auto& s: parser.sections())
{
for(auto& c: s.second.m_children)
{
dotfile << " " << s.second.m_number << " -> " << c << ";\n";
}
if(s.second.m_children.size() == 0)
{
dotfile << " " << s.second.m_number << " [peripheries=2];\n";
}
}
dotfile << "}\n";
}
return 0;
}
\ No newline at end of file
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment