⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graphviz_parser.yy

📁 boost库提供标准的C++ API 配合dev c++使用,功能更加强大
💻 YY
📖 第 1 页 / 共 2 页
字号:
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 + -