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.
kscope/src/dotparse.ypp

235 lines
3.6 KiB

/* dot.y */
%{
#include <ntqdict.h>
#include <ntqptrstack.h>
#include <ntqlistview.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 TQMap<TQString, TQString> s_pMapAttr;
static TQStack<TQListViewItem> s_pParentStack;
static TQListView* 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 {
TQString* 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 '}'
{
TQListViewItem* pItem;
pItem = s_pParentStack.pop();
if (pItem->firstChild() != NULL)
pItem->setOpen(true);
}
;
root_tree_node
: NAME
{
TQListViewItem* pItem;
pItem = new TQListViewItem(s_pTree, *$1);
s_pParentStack.push(pItem);
delete $1;
}
;
child_list
:
| child_node child_list
;
child_node
: tree_node tree_attributes '{' child_list '}'
{
TQListViewItem* pItem;
pItem = s_pParentStack.pop();
if (pItem->firstChild() != NULL)
pItem->setOpen(true);
}
;
tree_node
: NAME
{
TQListViewItem* pItem;
pItem = new TQListViewItem(s_pParentStack.top(), *$1);
s_pParentStack.push(pItem);
delete $1;
}
;
tree_attributes
: attributes
{
TQListViewItem* 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);
}