summaryrefslogtreecommitdiffstats
path: root/src/dotparse.ypp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotparse.ypp')
-rw-r--r--src/dotparse.ypp234
1 files changed, 234 insertions, 0 deletions
diff --git a/src/dotparse.ypp b/src/dotparse.ypp
new file mode 100644
index 0000000..f21b9e3
--- /dev/null
+++ b/src/dotparse.ypp
@@ -0,0 +1,234 @@
+/* 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);
+}