You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
235 lines
3.6 KiB
235 lines
3.6 KiB
11 years ago
|
/* dot.y */
|
||
|
|
||
|
%{
|
||
|
#include <qdict.h>
|
||
|
#include <qptrstack.h>
|
||
|
#include <qlistview.h>
|
||
|
#include "calltreedlg.h"
|
||
|
#include "graphwidget.h"
|
||
|
#include "treewidget.h"
|
||
|
#include "encoder.h"
|
||
|
|
||
|
extern FILE* yyin;
|
||
|
int yylex();
|
||
|
void yyinit(CallTreeDlg*, FILE*, Encoder*);
|
||
|
void yyerror(const char*);
|
||
|
|
||
|
static QMap<QString, QString> s_pMapAttr;
|
||
|
static QStack<QListViewItem> s_pParentStack;
|
||
|
static QListView* s_pTree;
|
||
|
|
||
|
static GraphWidget* s_pGraph;
|
||
|
static TreeWidget* s_pCallTree;
|
||
|
static TreeWidget* s_pCallingTree;
|
||
|
static Encoder* s_pEncoder;
|
||
|
|
||
|
// Avoid compiler warnings
|
||
|
#define YYENABLE_NLS 0
|
||
|
#ifndef YYLTYPE_IS_TRIVIAL
|
||
|
#define YYLTYPE_IS_TRIVIAL 0
|
||
|
#endif
|
||
|
%}
|
||
|
|
||
|
%union {
|
||
|
QString* pText;
|
||
|
}
|
||
|
|
||
|
%token GRAPH DIGRAPH NODE NAME STRING NUMBER DIR_EDGE UNDIR_EDGE
|
||
|
%token CALL_TREE CALLING_TREE
|
||
|
%type <pText> NAME STRING NUMBER attr_val
|
||
|
|
||
|
%start file
|
||
|
|
||
|
%%
|
||
|
|
||
|
file
|
||
|
: call_tree calling_tree graph
|
||
|
|
||
|
graph
|
||
|
: graph_type NAME '{' graph_desc_list '}' { delete $2; }
|
||
|
;
|
||
|
|
||
|
graph_type
|
||
|
: GRAPH
|
||
|
| DIGRAPH
|
||
|
;
|
||
|
|
||
|
graph_desc_list
|
||
|
:
|
||
|
| graph_desc_entry graph_desc_list
|
||
|
;
|
||
|
|
||
|
graph_desc_entry
|
||
|
: def_node_attr
|
||
|
| graph_attr
|
||
|
| node_record
|
||
|
| edge_record
|
||
|
;
|
||
|
|
||
|
def_node_attr
|
||
|
: NODE attributes ';'
|
||
|
;
|
||
|
|
||
|
graph_attr
|
||
|
: GRAPH attributes ';'
|
||
|
{
|
||
|
if (s_pMapAttr.find("kscope_zoom") != s_pMapAttr.end())
|
||
|
s_pGraph->setZoom(s_pMapAttr["kscope_zoom"].toDouble());
|
||
|
}
|
||
|
;
|
||
|
|
||
|
node_record
|
||
|
: NAME attributes ';'
|
||
|
{
|
||
|
s_pGraph->addNode(*$1);
|
||
|
delete $1;
|
||
|
s_pMapAttr.clear();
|
||
|
}
|
||
|
;
|
||
|
|
||
|
edge_record
|
||
|
: NAME edge_type NAME attributes ';'
|
||
|
{
|
||
|
GraphWidget::CallData cd;
|
||
|
|
||
|
cd.m_sCaller = *$1;
|
||
|
cd.m_sCallee = *$3;
|
||
|
cd.m_sFile = s_pMapAttr["kscope_file"];
|
||
|
cd.m_sLine = s_pMapAttr["kscope_line"];
|
||
|
cd.m_sText = s_pEncoder->decode(s_pMapAttr["kscope_text"]);
|
||
|
s_pGraph->addCall(cd);
|
||
|
|
||
|
delete $1;
|
||
|
delete $3;
|
||
|
s_pMapAttr.clear();
|
||
|
}
|
||
|
;
|
||
|
|
||
|
edge_type
|
||
|
: DIR_EDGE
|
||
|
| UNDIR_EDGE
|
||
|
;
|
||
|
|
||
|
attributes
|
||
|
:
|
||
|
| '[' attr_list ']'
|
||
|
;
|
||
|
|
||
|
attr_list
|
||
|
:
|
||
|
| non_empty_attr_list
|
||
|
;
|
||
|
|
||
|
non_empty_attr_list
|
||
|
: attr
|
||
|
| attr ',' attr_list
|
||
|
;
|
||
|
|
||
|
attr
|
||
|
: NAME '=' attr_val
|
||
|
{
|
||
|
s_pMapAttr.insert(*$1, *$3);
|
||
|
delete $1;
|
||
|
delete $3;
|
||
|
}
|
||
|
;
|
||
|
|
||
|
attr_val
|
||
|
: NAME
|
||
|
| STRING
|
||
|
| NUMBER
|
||
|
;
|
||
|
|
||
|
call_tree
|
||
|
: call_tree_prepare '{' root_node '}'
|
||
|
;
|
||
|
|
||
|
call_tree_prepare
|
||
|
: CALL_TREE { s_pTree = s_pCallTree; }
|
||
|
;
|
||
|
|
||
|
calling_tree
|
||
|
: calling_tree_prepare '{' root_node '}'
|
||
|
;
|
||
|
|
||
|
calling_tree_prepare
|
||
|
: CALLING_TREE { s_pTree = s_pCallingTree; }
|
||
|
;
|
||
|
|
||
|
root_node
|
||
|
: root_tree_node '{' child_list '}'
|
||
|
{
|
||
|
QListViewItem* pItem;
|
||
|
|
||
|
pItem = s_pParentStack.pop();
|
||
|
if (pItem->firstChild() != NULL)
|
||
|
pItem->setOpen(true);
|
||
|
}
|
||
|
;
|
||
|
|
||
|
root_tree_node
|
||
|
: NAME
|
||
|
{
|
||
|
QListViewItem* pItem;
|
||
|
|
||
|
pItem = new QListViewItem(s_pTree, *$1);
|
||
|
s_pParentStack.push(pItem);
|
||
|
delete $1;
|
||
|
}
|
||
|
;
|
||
|
|
||
|
child_list
|
||
|
:
|
||
|
| child_node child_list
|
||
|
;
|
||
|
|
||
|
child_node
|
||
|
: tree_node tree_attributes '{' child_list '}'
|
||
|
{
|
||
|
QListViewItem* pItem;
|
||
|
|
||
|
pItem = s_pParentStack.pop();
|
||
|
if (pItem->firstChild() != NULL)
|
||
|
pItem->setOpen(true);
|
||
|
}
|
||
|
;
|
||
|
|
||
|
tree_node
|
||
|
: NAME
|
||
|
{
|
||
|
QListViewItem* pItem;
|
||
|
|
||
|
pItem = new QListViewItem(s_pParentStack.top(), *$1);
|
||
|
s_pParentStack.push(pItem);
|
||
|
delete $1;
|
||
|
}
|
||
|
;
|
||
|
|
||
|
tree_attributes
|
||
|
: attributes
|
||
|
{
|
||
|
QListViewItem* pItem;
|
||
|
|
||
|
pItem = s_pParentStack.top();
|
||
|
pItem->setText(1, s_pMapAttr["kscope_file"]);
|
||
|
pItem->setText(2, s_pMapAttr["kscope_line"]);
|
||
|
pItem->setText(3, s_pEncoder->decode(s_pMapAttr["kscope_text"]));
|
||
|
}
|
||
|
;
|
||
|
|
||
|
%%
|
||
|
|
||
|
void yyinit(CallTreeDlg* pDlg, FILE* pFile, Encoder* pEnc)
|
||
|
{
|
||
|
yyin = pFile;
|
||
|
s_pCallTree = pDlg->m_pCalledWidget;
|
||
|
s_pCallingTree = pDlg->m_pCallingWidget;
|
||
|
s_pGraph = pDlg->m_pGraphWidget;
|
||
|
s_pEncoder = pEnc;
|
||
|
}
|
||
|
|
||
|
void yyerror(const char* szError)
|
||
|
{
|
||
|
fprintf(stderr, "%s\n", szError);
|
||
|
}
|