📄 graphviz_parser.yy
字号:
graph_body: '{' stmt_list '}' {$$=0;}
;
graph_header: graph_type graph_name
{
std::string* name = static_cast<std::string*>($2);
graphviz::previous_graph = static_cast<graphviz::Subgraph*>(g);
graphviz::current_graph = static_cast<graphviz::Subgraph*>(g);
graphviz::set_graph_name(*name);
delete name;
}
;
graph_type: GRAPH_T | DIGRAPH_T
;
graph_name: ID_T {$$ = $1; } | {$$=(void*)(new std::string("G")); }
;
stmt_list: stmt_list stmt | stmt
;
semicolon: ';' |
;
stmt: attr_stmt semicolon |
compound_stmt semicolon
;
attr_stmt: attr_header '[' attr_list ']'
{
graphviz::set_attribute(*graphviz::current_graph,
graphviz::attribute_state);
}
;
attr_header: GRAPH_T { graphviz::attribute_state = GRAPH_GRAPH_A; }
| NODE_T { graphviz::attribute_state = GRAPH_NODE_A; }
| EDGE_T { graphviz::attribute_state = GRAPH_EDGE_A; }
;
attr_list: attr | attr_list attr_separator attr
;
attr: ID_T '=' ID_T
{
std::string* name = static_cast<std::string*>($1);
std::string* value = static_cast<std::string*>($3);
graphviz::attributes[*name] = *value;
delete name;
delete value;
}
;
attr_separator: ';' | ',' |
;
compound_stmt: node_stmt | edge_stmt | graph_attr | subgraph { $$ = 0; }
;
graph_attr : attr
{
graphviz::set_attribute(
*static_cast<graphviz::Subgraph*>(graphviz::current_graph),
GRAPH_GRAPH_A);
}
;
node_stmt: node_id opt_attr
{
graphviz::Vertex* temp = static_cast<graphviz::Vertex*>($1);
graphviz::current_vertex = *temp;
graphviz::set_attribute(*static_cast<GRAPHVIZ_GRAPH*>(YYPARSE_PARAM),
NODE_A);
delete temp;
$$ = 0;
}
;
opt_attr: '[' attr_list ']' { $$=0; } | { $$=0; }
;
node_id: ID_T
{
std::string* name = static_cast<std::string*>($1);
std::pair<graphviz::Iter, bool> result = graphviz::lookup(*name);
if (result.second) {
graphviz::current_vertex = result.first->second;
if (! graphviz::current_graph->is_root())
boost::add_vertex(graphviz::current_vertex, *graphviz::current_graph);
} else
graphviz::current_vertex = graphviz::add_name(*name, *static_cast<GRAPHVIZ_GRAPH*>(YYPARSE_PARAM)) ;
graphviz::Vertex* temp = new graphviz::Vertex(graphviz::current_vertex);
$$ = (void *)temp;
graphviz::attribute_state = NODE_A;
delete name;
}
| node_port { $$=$1; }
;
node_port: ID_T ':' ID_T
{
//consider port as a special properties ?? --need work here
std::string* name = static_cast<std::string*>($1);
std::string* port = static_cast<std::string*>($3);
std::pair<graphviz::Iter, bool> result = graphviz::lookup(*name);
if (result.second)
graphviz::current_vertex = result.first->second;
else
graphviz::current_vertex = graphviz::add_name(*name, *static_cast<GRAPHVIZ_GRAPH*>(YYPARSE_PARAM)) ;
graphviz::Vertex* temp = new graphviz::Vertex(graphviz::current_vertex);
$$ = (void *)temp;
graphviz::attribute_state = NODE_A;
delete name;
delete port;
}
;
edge_stmt: edge_endpoint edge_rhs opt_attr
{
typedef std::pair<void*, bool>* Ptr;
Ptr source = static_cast<Ptr>($1);
for (std::vector<Ptr>::iterator it=graphviz::vlist.begin();
it !=graphviz::vlist.end(); ++it) {
if ( source->second ) {
if ( (*it)->second )
graphviz::add_edges(static_cast<graphviz::Subgraph*>(source->first),
static_cast<graphviz::Subgraph*>((*it)->first),
*static_cast<GRAPHVIZ_GRAPH*>(YYPARSE_PARAM));
else
graphviz::add_edges(static_cast<graphviz::Subgraph*>(source->first),
*static_cast<graphviz::Vertex*>((*it)->first),
*static_cast<GRAPHVIZ_GRAPH*>(YYPARSE_PARAM));
} else {
graphviz::Vertex* temp = static_cast<graphviz::Vertex*>(source->first);
if ( (*it)->second )
graphviz::add_edges(*temp,
static_cast<graphviz::Subgraph*>((*it)->first),
*static_cast<GRAPHVIZ_GRAPH*>(YYPARSE_PARAM));
else
graphviz::add_edges(*temp,
*static_cast<graphviz::Vertex*>((*it)->first),
*static_cast<GRAPHVIZ_GRAPH*>(YYPARSE_PARAM));
delete temp;
}
delete source;
source = *it;
}
if ( ! source->second ) {
graphviz::Vertex* temp = static_cast<graphviz::Vertex*>(source->first);
delete temp;
}
delete source;
graphviz::attributes.clear();
graphviz::vlist.clear();
}
;
edge_rhs_one: EDGEOP_T edge_endpoint
{ graphviz::vlist.push_back(static_cast<std::pair<void*, bool>*>($2)); }
;
edge_rhs: edge_rhs_one | edge_rhs edge_rhs_one
;
edge_endpoint: node_id
{
std::pair<void*, bool>* temp = new std::pair<void*, bool>;
temp->first = $1;
temp->second = false;
$$ = (void*)temp;
graphviz::attribute_state = EDGE_A;
}
| subgraph
{
std::pair<void*, bool>* temp = new std::pair<void*, bool>;
temp->first = $1;
temp->second = true;
$$ = (void*)temp;
graphviz::attribute_state = EDGE_A;
}
;
subgraph: subgraph_header opt_graph_body
{
if ( $2 )
graphviz::current_graph = &graphviz::current_graph->parent();
else
graphviz::current_graph = graphviz::previous_graph;
}
|
{
graphviz::previous_graph = graphviz::current_graph;
std::string name = graphviz::random_string();
graphviz::Subgraph* temp = graphviz::create_subgraph(name);
graphviz::current_graph = temp;
graphviz::set_graph_name(name);
$$ = (void *) graphviz::current_graph;
} graph_body
{
graphviz::current_graph = &graphviz::current_graph->parent();
}
;
subgraph_header: SUBGRAPH_T ID_T
{
//lookup ID_T if it is already in the subgraph,
//if it is not, add a new subgraph
std::string* name = static_cast<std::string*>($2);
std::pair<graphviz::It, bool> temp = graphviz::lookup_subgraph(*name);
graphviz::previous_graph = graphviz::current_graph;
if ( temp.second ) {//found
graphviz::current_graph = (temp.first)->second;
} else {
graphviz::current_graph = graphviz::create_subgraph(*name);
graphviz::set_graph_name(*name);
}
$$ = (void *) graphviz::current_graph;
delete name;
}
;
opt_graph_body: graph_body {$$ = 1; } | { $$ = 0; }
;
%%
namespace boost {
void read_graphviz(const std::string& filename, GRAPHVIZ_GRAPH& g) {
FILE* file = fopen(filename.c_str(), "r");
yyrestart(file);
void* in = static_cast<void*>(file);
yyparse(static_cast<void*>(&g));
}
void read_graphviz(FILE* file, GRAPHVIZ_GRAPH& g) {
void* in = static_cast<void*>(file);
yyrestart(file);
yyparse(static_cast<void*>(&g));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -