diff options
author | Aleks Kissinger <aleks0@gmail.com> | 2017-01-22 14:19:41 +0100 |
---|---|---|
committer | Aleks Kissinger <aleks0@gmail.com> | 2017-01-22 14:19:41 +0100 |
commit | df9f92b955ceb18a89b68dacdc3a2ab820a36123 (patch) | |
tree | 45fc97744261db1a9ce0a1078129bf805165be3a /tikzit/src/data | |
parent | 48e69ae28bb8b40d5a2281f0ea26141220b3bf5e (diff) |
parsing
Diffstat (limited to 'tikzit/src/data')
-rw-r--r-- | tikzit/src/data/edge.cpp | 15 | ||||
-rw-r--r-- | tikzit/src/data/edge.h | 14 | ||||
-rw-r--r-- | tikzit/src/data/graph.cpp | 24 | ||||
-rw-r--r-- | tikzit/src/data/graph.h | 7 | ||||
-rw-r--r-- | tikzit/src/data/tikzgraphassembler.cpp | 21 | ||||
-rw-r--r-- | tikzit/src/data/tikzgraphassembler.h | 2 | ||||
-rw-r--r-- | tikzit/src/data/tikzlexer.l | 21 | ||||
-rw-r--r-- | tikzit/src/data/tikzparser.y | 109 | ||||
-rw-r--r-- | tikzit/src/data/tikzparserdefs.h | 3 |
9 files changed, 147 insertions, 69 deletions
diff --git a/tikzit/src/data/edge.cpp b/tikzit/src/data/edge.cpp index c8d1cfc..67e2061 100644 --- a/tikzit/src/data/edge.cpp +++ b/tikzit/src/data/edge.cpp @@ -1,14 +1,18 @@ #include "edge.h" +#include <QDebug> + Edge::Edge(Node *s, Node *t, QObject *parent) : QObject(parent), _source(s), _target(t) { _data = new GraphElementData(); + _edgeNode = 0; } Edge::~Edge() { delete _data; + delete _edgeNode; } Node *Edge::source() const @@ -52,4 +56,15 @@ void Edge::setTargetAnchor(const QString &targetAnchor) _targetAnchor = targetAnchor; } +Node *Edge::edgeNode() const +{ + return _edgeNode; +} + +void Edge::setEdgeNode(Node *edgeNode) +{ + if (_edgeNode != 0) delete _edgeNode; + _edgeNode = edgeNode; +} + diff --git a/tikzit/src/data/edge.h b/tikzit/src/data/edge.h index 5884b90..90e624e 100644 --- a/tikzit/src/data/edge.h +++ b/tikzit/src/data/edge.h @@ -26,16 +26,24 @@ public: QString targetAnchor() const; void setTargetAnchor(const QString &targetAnchor); + Node *edgeNode() const; + void setEdgeNode(Node *edgeNode); + signals: public slots: private: - Node *_source; - Node *_target; - GraphElementData *_data; QString _sourceAnchor; QString _targetAnchor; + + // owned + Node *_edgeNode; + GraphElementData *_data; + + // referenced + Node *_source; + Node *_target; }; #endif // EDGE_H diff --git a/tikzit/src/data/graph.cpp b/tikzit/src/data/graph.cpp index 8a995d2..9307d62 100644 --- a/tikzit/src/data/graph.cpp +++ b/tikzit/src/data/graph.cpp @@ -11,19 +11,25 @@ Graph::~Graph() } void Graph::removeNode(Node *n) { - nodes.removeAll(n); + _nodes.removeAll(n); inEdges.remove(n); outEdges.remove(n); } Edge *Graph::addEdge(Node *s, Node *t) { - + Edge *e = new Edge(s, t, this); + _edges << e; + outEdges.insert(s, e); + inEdges.insert(t, e); + return e; } void Graph::removeEdge(Edge *e) { - + _edges.removeAll(e); + outEdges.remove(e->source(), e); + inEdges.remove(e->target(), e); } GraphElementData *Graph::data() const @@ -37,9 +43,19 @@ void Graph::setData(GraphElementData *data) _data = data; } +const QVector<Node*> &Graph::nodes() +{ + return _nodes; +} + +const QVector<Edge*> &Graph::edges() +{ + return _edges; +} + Node *Graph::addNode() { Node *n = new Node(this); - nodes << n; + _nodes << n; return n; } diff --git a/tikzit/src/data/graph.h b/tikzit/src/data/graph.h index 1f26486..8f466a2 100644 --- a/tikzit/src/data/graph.h +++ b/tikzit/src/data/graph.h @@ -23,13 +23,16 @@ public: GraphElementData *data() const; void setData(GraphElementData *data); + const QVector<Node *> &nodes(); + const QVector<Edge*> &edges(); + signals: public slots: private: - QVector<Node*> nodes; - QVector<Edge*> edges; + QVector<Node*> _nodes; + QVector<Edge*> _edges; QMultiHash<Node*,Edge*> inEdges; QMultiHash<Node*,Edge*> outEdges; GraphElementData *_data; diff --git a/tikzit/src/data/tikzgraphassembler.cpp b/tikzit/src/data/tikzgraphassembler.cpp index d8e3963..c05a5c8 100644 --- a/tikzit/src/data/tikzgraphassembler.cpp +++ b/tikzit/src/data/tikzgraphassembler.cpp @@ -1,14 +1,31 @@ #include "tikzgraphassembler.h" +#include "tikzparserdefs.h" +#include "tikzparser.parser.hpp" +#include "tikzlexer.h" + +int yyparse(void *scanner); + + TikzGraphAssembler::TikzGraphAssembler(Graph *graph, QObject *parent) : - _graph(graph), QObject(parent) + QObject(parent), _graph(graph) { - + yylex_init(&scanner); + yyset_extra(this, scanner); } void TikzGraphAssembler::addNodeToMap(Node *n) { _nodeMap.insert(n->name(), n); } Node *TikzGraphAssembler::nodeWithName(QString name) { return _nodeMap[name]; } +bool TikzGraphAssembler::parse(const QString &tikz) +{ + yy_scan_string(tikz.toLatin1().data(), scanner); + int result = yyparse(scanner); + + if (result == 0) return true; + else return false; +} + Graph *TikzGraphAssembler::graph() const { return _graph; diff --git a/tikzit/src/data/tikzgraphassembler.h b/tikzit/src/data/tikzgraphassembler.h index 2ae42fd..79b89b0 100644 --- a/tikzit/src/data/tikzgraphassembler.h +++ b/tikzit/src/data/tikzgraphassembler.h @@ -14,6 +14,7 @@ public: explicit TikzGraphAssembler(Graph *graph, QObject *parent = 0); void addNodeToMap(Node *n); Node *nodeWithName(QString name); + bool parse(const QString &tikz); Graph *graph() const; @@ -24,6 +25,7 @@ public slots: private: QHash<QString,Node*> _nodeMap; Graph *_graph; + void *scanner; }; #endif // TIKZGRAPHASSEMBLER_H diff --git a/tikzit/src/data/tikzlexer.l b/tikzit/src/data/tikzlexer.l index adb6fef..8dd23c6 100644 --- a/tikzit/src/data/tikzlexer.l +++ b/tikzit/src/data/tikzlexer.l @@ -39,7 +39,6 @@ %option header-file="tikzlexer.h" %option extra-type="TikzGraphAssembler *" - %s props %s xcoord %s ycoord @@ -80,6 +79,7 @@ to { return TO; } BEGIN(xcoord); } <xcoord>{FLOAT} { + yylval->pt = new QPointF(); yylval->pt->setX(strtod(yytext,NULL)); BEGIN(ycoord); } @@ -103,7 +103,9 @@ to { return TO; } property names or values, but in practice this is unlikely and screws up our line counting */ <props>[^=,\{\] \t\n]([^=,\{\]\n]*[^=,\{\] \t\n])? { - yylval->qstr= new QString(yytext); + char *str = (char*)malloc(sizeof(char)*yyleng + 1); + strncpy(str, yytext, yyleng + 1); + yylval->str = str; return PROPSTRING; } <props>\] { @@ -121,7 +123,10 @@ to { return TO; } /* we assume node names (and anchor names) never contain newlines */ <noderef>[^\.\{\)\n]+ { - yylval->qstr = new QString(yytext); + //qDebug() << "nodename: " << yytext << " size: " << strlen(yytext); + char *str = (char*)malloc(sizeof(char)*yyleng + 1); + strncpy(str, yytext, yyleng+1); + yylval->str = str; return REFSTRING; } <noderef>\) { @@ -132,7 +137,7 @@ to { return TO; } <INITIAL,props>\{ { std::stringstream buf; unsigned int brace_depth = 1; - unsigned int escape = 0; + unsigned int escape = 0; while (1) { char c = yyinput(yyscanner); // eof reached before closing brace @@ -158,9 +163,11 @@ to { return TO; } buf << c; } - - - yylval->qstr = new QString(QString::fromStdString(buf.str())); + char *str = (char*)malloc(sizeof(char) * yyleng + 1); + strncpy(str, buf.str().c_str(), yyleng + 1); + //str[len] = 0; + yylval->str = str; + //qDebug() << "got delim string: " << str; return DELIMITEDSTRING; } diff --git a/tikzit/src/data/tikzparser.y b/tikzit/src/data/tikzparser.y index 39d89c6..970f5b4 100644 --- a/tikzit/src/data/tikzparser.y +++ b/tikzit/src/data/tikzparser.y @@ -41,7 +41,7 @@ /* possible data types for semantic values */ %union { - QString *qstr; + char *str; GraphElementProperty *prop; GraphElementData *data; Node *node; @@ -65,6 +65,7 @@ void yyerror(YYLTYPE *yylloc, void *scanner, const char *str) { // TODO: implement reportError() //assembler->reportError(str, yylloc); + qDebug() << "parse error: " << str; } %} @@ -97,9 +98,9 @@ void yyerror(YYLTYPE *yylloc, void *scanner, const char *str) { %token FULLSTOP "." %token EQUALS "=" %token <pt> COORD "co-ordinate" -%token <qstr> PROPSTRING "key/value string" -%token <qstr> REFSTRING "string" -%token <qstr> DELIMITEDSTRING "{-delimited string" +%token <str> PROPSTRING "key/value string" +%token <str> REFSTRING "string" +%token <str> DELIMITEDSTRING "{-delimited string" %token UNKNOWN_BEGIN_CMD "unknown \\begin command" %token UNKNOWN_END_CMD "unknown \\end command" @@ -107,9 +108,9 @@ void yyerror(YYLTYPE *yylloc, void *scanner, const char *str) { %token UNKNOWN_STR "unknown string" %token UNCLOSED_DELIM_STR "unclosed {-delimited string" -%type<qstr> nodename -%type<qstr> optanchor -%type<qstr> val +%type<str> nodename +%type<str> optanchor +%type<str> val %type<prop> property %type<data> extraproperties %type<data> properties @@ -121,8 +122,8 @@ void yyerror(YYLTYPE *yylloc, void *scanner, const char *str) { %% tikzpicture: "\\begin{tikzpicture}" optproperties tikzcmds "\\end{tikzpicture}" - { - if ($2) { + { + if ($2) { assembler->graph()->setData($2); } }; @@ -141,27 +142,28 @@ properties: extraproperties property { $1->add(*$2); delete $2; - $$ = $1; + $$ = $1; }; extraproperties: extraproperties property "," { $1->add(*$2); delete $2; - $$ = $1; + $$ = $1; } | { $$ = new GraphElementData(); }; property: val "=" val { - GraphElementProperty *p = new GraphElementProperty(*$1,*$3); - delete $1, $3; + GraphElementProperty *p = new GraphElementProperty(QString($1),QString($3)); + free($1); + free($3); $$ = p; } | val { - GraphElementProperty *a = new GraphElementProperty(*$1); - delete $1; + GraphElementProperty *a = new GraphElementProperty(QString($1)); + free($1); $$ = a; }; val: PROPSTRING { $$ = $1; } | DELIMITEDSTRING { $$ = $1; }; @@ -173,18 +175,23 @@ node: "\\node" optproperties nodename "at" COORD DELIMITEDSTRING ";" if ($2) { node->setData($2); } - node->setName(*$3); + //qDebug() << "node name: " << $3; + node->setName(QString($3)); + node->setLabel(QString($6)); + free($3); + free($6); + node->setPoint(*$5); - node->setLabel(*$6); - delete $3, $5, $6; - assembler->addNodeToMap(node); + delete $5; + + assembler->addNodeToMap(node); }; optanchor: { $$ = 0; } | "." REFSTRING { $$ = $2; }; noderef: "(" REFSTRING optanchor ")" { - $$.node = assembler->nodeWithName(*$2); - delete $2; + $$.node = assembler->nodeWithName(QString($2)); + free($2); $$.anchor = $3; }; optnoderef: @@ -193,42 +200,44 @@ optnoderef: optedgenode: { $$ = 0; } | "node" optproperties DELIMITEDSTRING - { - // TODO: implement edge-nodes - // $$ = [Node node]; - // if ($2) - // [$$ setData:$2]; - // [$$ setLabel:$3]; + { + $$ = new Node(); + if ($2) + $$->setData($2); + $$->setLabel(QString($3)); + free($3); } edge: "\\draw" optproperties noderef "to" optedgenode optnoderef ";" { - Node *s; - Node *t; - Node *en; - - QString sa; - QString ta; - - // TODO: anchors and edge nodes + Node *s; + Node *t; - s = $3.node; - sa = *$3.anchor; - delete $3.anchor; - if ($6.node) { - t = $6.node; - ta = *$6.anchor; - delete $6.anchor; - } else { + s = $3.node; + + if ($6.node) { + t = $6.node; + } else { t = s; - ta = sa; - } + } - Edge *edge = assembler->graph()->addEdge(s, t); - if ($2) - edge->setData($2); + Edge *edge = assembler->graph()->addEdge(s, t); + if ($2) + edge->setData($2); + if ($5) + edge->setEdgeNode($5); + if ($3.anchor) { + edge->setSourceAnchor(QString($3.anchor)); + free($3.anchor); + } - edge->setSourceAnchor(sa); - edge->setTargetAnchor(ta); + if ($6.node) { + if ($6.anchor) { + edge->setTargetAnchor(QString($6.anchor)); + free($6.anchor); + } + } else { + edge->setTargetAnchor(edge->sourceAnchor()); + } }; ignoreprop: val | val "=" val; diff --git a/tikzit/src/data/tikzparserdefs.h b/tikzit/src/data/tikzparserdefs.h index 7ba5bc5..b6a904b 100644 --- a/tikzit/src/data/tikzparserdefs.h +++ b/tikzit/src/data/tikzparserdefs.h @@ -7,10 +7,11 @@ #include "tikzgraphassembler.h" #include <QString> +#include <QDebug> struct noderef { Node *node; - QString *anchor; + char *anchor; }; #endif // TIKZPARSERDEFS_H |