summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Merry <dev@randomguy3.me.uk>2013-03-23 00:45:23 +0000
committerAlex Merry <dev@randomguy3.me.uk>2013-03-23 00:45:23 +0000
commit2aa4afed415b02add73c2dd5a3e9ccab90066d04 (patch)
treeaf135f127514fe047cb99b4f0c2ea7b87162acab
parentdbd620bbaf7f28728c2686737b6a1453caaebd25 (diff)
Make the parser more coherent
We build things up in stacks in the parser, rather than relying on TikzGraphAssembler so much. This makes tikzparser.ym easier to follow (IMHO).
-rw-r--r--tikzit/src/common/GraphElementData.h2
-rw-r--r--tikzit/src/common/GraphElementData.m4
-rw-r--r--tikzit/src/common/GraphElementProperty.h3
-rw-r--r--tikzit/src/common/GraphElementProperty.m10
-rw-r--r--tikzit/src/common/TikzGraphAssembler+Parser.h33
-rw-r--r--tikzit/src/common/TikzGraphAssembler.h13
-rw-r--r--tikzit/src/common/TikzGraphAssembler.m83
-rw-r--r--tikzit/src/common/tikzlexer.lm44
-rw-r--r--tikzit/src/common/tikzparser.ym191
9 files changed, 191 insertions, 192 deletions
diff --git a/tikzit/src/common/GraphElementData.h b/tikzit/src/common/GraphElementData.h
index e5ff4d7..a65e6df 100644
--- a/tikzit/src/common/GraphElementData.h
+++ b/tikzit/src/common/GraphElementData.h
@@ -40,6 +40,8 @@
NSMutableArray *properties;
}
+- (id)init;
++ (id)data;
/*!
@brief Set the given value for the *first* property matching this key. Add a
diff --git a/tikzit/src/common/GraphElementData.m b/tikzit/src/common/GraphElementData.m
index fd93a0d..a99a432 100644
--- a/tikzit/src/common/GraphElementData.m
+++ b/tikzit/src/common/GraphElementData.m
@@ -27,6 +27,10 @@
@implementation GraphElementData
++ (id)data {
+ return [[[self alloc] init] autorelease];
+}
+
- (id)init {
[super init];
properties = [[NSMutableArray alloc] init];
diff --git a/tikzit/src/common/GraphElementProperty.h b/tikzit/src/common/GraphElementProperty.h
index 3ca93dc..029e7f3 100644
--- a/tikzit/src/common/GraphElementProperty.h
+++ b/tikzit/src/common/GraphElementProperty.h
@@ -46,6 +46,7 @@
@result A key-matching object.
*/
- (id)initWithKeyMatching:(NSString*)k;
++ (id)keyMatching:(NSString*)k;
/*!
@brief Initialize a new atomic property.
@@ -53,6 +54,7 @@
@result An atom.
*/
- (id)initWithAtomName:(NSString*)n;
++ (id)atom:(NSString*)n;
/*!
@brief Initialize a new property.
@@ -61,6 +63,7 @@
@result A property.
*/
- (id)initWithPropertyValue:(NSString*)v forKey:(NSString*)k;
++ (id)property:(NSString*)k withValue:(NSString*)v;
/*!
@brief A matching function for properties.
diff --git a/tikzit/src/common/GraphElementProperty.m b/tikzit/src/common/GraphElementProperty.m
index 2eb6a5f..1e8ad3a 100644
--- a/tikzit/src/common/GraphElementProperty.m
+++ b/tikzit/src/common/GraphElementProperty.m
@@ -27,6 +27,16 @@
@implementation GraphElementProperty
++ (id)atom:(NSString*)n {
+ return [[[self alloc] initWithAtomName:n] autorelease];
+}
++ (id)property:(NSString*)k withValue:(NSString*)v {
+ return [[[self alloc] initWithPropertyValue:v forKey:k] autorelease];
+}
++ (id)keyMatching:(NSString*)k {
+ return [[[self alloc] initWithKeyMatching:k] autorelease];
+}
+
- (id)initWithAtomName:(NSString*)n {
[super init];
[self setKey:n];
diff --git a/tikzit/src/common/TikzGraphAssembler+Parser.h b/tikzit/src/common/TikzGraphAssembler+Parser.h
new file mode 100644
index 0000000..683e3e2
--- /dev/null
+++ b/tikzit/src/common/TikzGraphAssembler+Parser.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2013 Alex Merry <dev@randomguy3.me.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * TikzGraphAssember+Parser.h
+ *
+ * This file exposes some TikzGraphAssembler functions
+ * that are only of use to the parser.
+ */
+
+#import "TikzGraphAssembler.h"
+
+@interface TikzGraphAssembler (Parser)
+/** Store a node so that it can be looked up by name later */
+- (void)addNodeToMap:(Node*)n;
+- (Node*)nodeWithName:(NSString*)name;
+@end
+
+// vi:ft=objc:noet:ts=4:sts=4:sw=4
diff --git a/tikzit/src/common/TikzGraphAssembler.h b/tikzit/src/common/TikzGraphAssembler.h
index a0c8a0d..3fc4e9e 100644
--- a/tikzit/src/common/TikzGraphAssembler.h
+++ b/tikzit/src/common/TikzGraphAssembler.h
@@ -26,16 +26,11 @@
@interface TikzGraphAssembler : NSObject {
Graph *graph;
- Node *currentNode;
- Edge *currentEdge;
NSMutableDictionary *nodeMap;
NSError *lastError;
}
@property (readonly) Graph *graph;
-@property (readonly) GraphElementData *data;
-@property (readonly) Node *currentNode;
-@property (readonly) Edge *currentEdge;
@property (readonly) NSError *lastError;
- (BOOL)parseTikz:(NSString*)tikz;
@@ -43,14 +38,6 @@
- (BOOL)testTikz:(NSString*)tikz;
-- (void)prepareNode;
-- (void)finishNode;
-
-- (void)prepareEdge;
-- (void)setEdgeSource:(NSString*)edge anchor:(NSString*)anch;
-- (void)setEdgeTarget:(NSString*)edge anchor:(NSString*)anch;
-- (void)finishEdge;
-
- (void)invalidate;
- (void)invalidateWithError:(NSError*)error;
diff --git a/tikzit/src/common/TikzGraphAssembler.m b/tikzit/src/common/TikzGraphAssembler.m
index 8400cf6..26bf515 100644
--- a/tikzit/src/common/TikzGraphAssembler.m
+++ b/tikzit/src/common/TikzGraphAssembler.m
@@ -77,29 +77,18 @@ int yywrap() {
@implementation TikzGraphAssembler
- (id)init {
- [super init];
- graph = nil;
- currentNode = nil;
- currentEdge = nil;
- nodeMap = nil;
+ self = [super init];
return self;
}
-- (Graph*)graph { return graph; }
-- (NSError*)lastError { return lastError; }
-
-- (GraphElementData *)data {
- if (currentNode != nil) {
- return [currentNode data];
- } else if (currentEdge != nil) {
- return [currentEdge data];
- } else {
- return [graph data];
- }
+- (void)dealloc {
+ [graph release];
+ [lastError release];
+ [super dealloc];
}
-- (Node*)currentNode { return currentNode; }
-- (Edge*)currentEdge { return currentEdge; }
+- (Graph*)graph { return graph; }
+- (NSError*)lastError { return lastError; }
- (BOOL)parseTikz:(NSString *)tikz {
return [self parseTikz:tikz forGraph:[Graph graph]];
@@ -170,55 +159,6 @@ int yywrap() {
return r;
}
-- (void)prepareNode {
- currentNode = [[Node alloc] init];
-}
-
-- (void)finishNode {
- if (currentEdge != nil) { // this is an edge node
- [currentEdge setEdgeNode:currentNode];
- } else { // this is a normal node
- [graph addNode:currentNode];
- [nodeMap setObject:currentNode forKey:[currentNode name]];
- }
-
- [currentNode release];
- currentNode = nil;
-}
-
-- (void)prepareEdge {
- currentEdge = [[Edge alloc] init];
-}
-
-- (void)finishEdge {
- [currentEdge setAttributesFromData];
- [graph addEdge:currentEdge];
- [currentEdge release];
- currentEdge = nil;
-}
-
-- (void)setEdgeSource:(NSString*)edge anchor:(NSString*)anch {
- Node *s = [nodeMap objectForKey:edge];
- [currentEdge setSource:s];
- [currentEdge setSourceAnchor:anch];
-}
-
-- (void)setEdgeTarget:(NSString*)edge anchor:(NSString*)anch {
- if (![edge isEqualToString:@""]) {
- [currentEdge setTarget:[nodeMap objectForKey:edge]];
- [currentEdge setTargetAnchor:anch];
- } else {
- [currentEdge setTargetAnchor:anch];
- [currentEdge setTarget:[currentEdge source]];
- }
-}
-
-- (void)dealloc {
- [graph release];
- [lastError release];
- [super dealloc];
-}
-
- (void)invalidate {
[graph release];
graph = nil;
@@ -244,4 +184,13 @@ int yywrap() {
@end
+@implementation TikzGraphAssembler (Parser)
+- (void)addNodeToMap:(Node*)n {
+ [nodeMap setObject:n forKey:[n name]];
+}
+- (Node*)nodeWithName:(NSString*)name {
+ return [nodeMap objectForKey:name];
+}
+@end
+
// vi:ft=objc:ts=4:noet:sts=4:sw=4
diff --git a/tikzit/src/common/tikzlexer.lm b/tikzit/src/common/tikzlexer.lm
index 3fd7b53..ad99445 100644
--- a/tikzit/src/common/tikzlexer.lm
+++ b/tikzit/src/common/tikzlexer.lm
@@ -7,31 +7,25 @@
FLOAT \-?[0-9]*(\.[0-9]+)?
%{
-//
-// tikzparser.l
-// TikZiT
-//
-// Copyright 2010 Chris Heunen. All rights reserved.
-// Copyright 2012 Aleks Kissinger
-// Copyright 2012 KJ
-// Copyright 2013 Alex Merry
-//
-//
-// This file is part of TikZiT.
-//
-// TikZiT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// TikZiT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with TikZiT. If not, see <http://www.gnu.org/licenses/>.
-//
+/*
+ * Copyright 2010 Chris Heunen
+ * Copyright 2010-2013 Aleks Kissinger
+ * Copyright 2013 K. Johan Paulsson
+ * Copyright 2013 Alex Merry <dev@randomguy3.me.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
#import <Foundation/Foundation.h>
#ifdef __APPLE__
diff --git a/tikzit/src/common/tikzparser.ym b/tikzit/src/common/tikzparser.ym
index 170106f..b81b74c 100644
--- a/tikzit/src/common/tikzparser.ym
+++ b/tikzit/src/common/tikzparser.ym
@@ -1,34 +1,29 @@
-// %expect 3
+%error-verbose
%{
-//
-// tikzparser.y
-// TikZiT
-//
-// Copyright 2010 Chris Heunen. All rights reserved.
-//
-//
-// This file is part of TikZiT.
-//
-// TikZiT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// TikZiT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with TikZiT. If not, see <http://www.gnu.org/licenses/>.
-//
-#include <stdio.h>
-#include <string.h>
-#import <Foundation/Foundation.h>
-#import "TikzGraphAssembler.h"
-#import "GraphElementProperty.h"
-
+/*
+ * Copyright 2010 Chris Heunen
+ * Copyright 2010-2013 Aleks Kissinger
+ * Copyright 2013 K. Johan Paulsson
+ * Copyright 2013 Alex Merry <dev@randomguy3.me.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#import "TikzGraphAssembler+Parser.h"
+#import "Edge.h"
+
extern char* yystr;
extern int yylineno;
extern int tokenpos;
@@ -37,12 +32,25 @@ extern void yyerror(const char *str);
%}
+%code requires {
+#import "GraphElementData.h"
+#import "GraphElementProperty.h"
+#import "Node.h"
+struct noderef {
+ Node *node;
+ NSString *anchor;
+};
+}
+
%union {
NSPoint pt;
NSString *nsstr;
+ GraphElementProperty *prop;
+ GraphElementData *data;
+ Node *node;
+ struct noderef noderef;
};
-%error-verbose
%token BEGIN_TIKZPICTURE_CMD
%token END_TIKZPICTURE_CMD
@@ -69,9 +77,16 @@ extern void yyerror(const char *str);
%token REFSTRING
%token DELIMITEDSTRING
-%type<nsstr> nodename
-%type<nsstr> optanchor
-%type<nsstr> val
+%type<nsstr> nodename
+%type<nsstr> optanchor
+%type<nsstr> val
+%type<prop> property
+%type<data> extraproperties
+%type<data> properties
+%type<data> optproperties
+%type<node> optedgenode
+%type<noderef> noderef
+%type<noderef> optnoderef
%%
@@ -81,72 +96,75 @@ tikzcmd: node | edge | boundingbox | ignore;
ignore: BEGIN_PGFONLAYER_CMD DELIMITEDSTRING | END_PGFONLAYER_CMD;
-optproperties: LEFTBRACKET properties RIGHTBRACKET | ;
-properties: property extraproperties;
-extraproperties: COMMA property extraproperties | ;
-property:
- val EQUALS val
+optproperties:
+ LEFTBRACKET properties RIGHTBRACKET
+ { $$ = $<data>2; }
+ | { $$ = nil; };
+properties: property extraproperties
{
- TikzGraphAssembler *a = [TikzGraphAssembler currentAssembler];
- GraphElementProperty *p = [[GraphElementProperty alloc] initWithPropertyValue:$<nsstr>3 forKey:$<nsstr>1];
- [[a data] addObject:p];
- [p release];
+ [$<data>2 addObject:$<prop>1];
+ $$ = $<data>2;
+ };
+extraproperties:
+ COMMA property extraproperties
+ {
+ [$<data>3 addObject:$<prop>2];
+ $$ = $<data>3;
}
+ | { $$ = [GraphElementData data]; };
+property:
+ val EQUALS val
+ { $$ = [GraphElementProperty property:$<nsstr>1 withValue:$<nsstr>3]; }
| val
- {
- TikzGraphAssembler *a = [TikzGraphAssembler currentAssembler];
- GraphElementProperty *p = [[GraphElementProperty alloc] initWithAtomName:$<nsstr>1];
- [[a data] addObject:p];
- [p release];
- };
+ { $$ = [GraphElementProperty atom:$<nsstr>1]; };
val: PROPSTRING { $$ = $<nsstr>1; } | DELIMITEDSTRING { $$ = $<nsstr>1; };
-nodecmd: NODE_CMD { [[TikzGraphAssembler currentAssembler] prepareNode]; };
nodename: LEFTPARENTHESIS REFSTRING RIGHTPARENTHESIS { $$ = $<nsstr>2; };
-node: nodecmd optproperties nodename AT COORD DELIMITEDSTRING SEMICOLON
+node: NODE_CMD optproperties nodename AT COORD DELIMITEDSTRING SEMICOLON
{
- TikzGraphAssembler *a = [TikzGraphAssembler currentAssembler];
- [[a currentNode] setName:$<nsstr>3];
- [[a currentNode] setPoint:$<pt>5];
- [[a currentNode] setLabel:$<nsstr>6];
- [a finishNode];
+ Node *node = [Node node];
+ [node setData:$<data>2];
+ [node setName:$<nsstr>3];
+ [node setPoint:$<pt>5];
+ [node setLabel:$<nsstr>6];
+ [[TikzGraphAssembler currentAssembler] addNodeToMap:node];
+ [[[TikzGraphAssembler currentAssembler] graph] addNode:node];
};
-edgecmd : DRAW_CMD { [[TikzGraphAssembler currentAssembler] prepareEdge]; };
-edge: edgecmd optproperties source TO optedgenode target SEMICOLON
+optanchor: { $$ = nil; } | FULLSTOP REFSTRING { $$ = $<nsstr>2; };
+noderef: LEFTPARENTHESIS REFSTRING optanchor RIGHTPARENTHESIS
{
- TikzGraphAssembler *a = [TikzGraphAssembler currentAssembler];
- [a finishEdge];
+ $$.node = [[TikzGraphAssembler currentAssembler] nodeWithName:$<nsstr>2];
+ $$.anchor = $<nsstr>3;
};
-optanchor: { $$ = @""; } | FULLSTOP REFSTRING { $$ = $<nsstr>2; };
-source: LEFTPARENTHESIS REFSTRING optanchor RIGHTPARENTHESIS
- {
- TikzGraphAssembler *a = [TikzGraphAssembler currentAssembler];
- [a setEdgeSource:$<nsstr>2
- anchor:$<nsstr>3];
- };
-target: LEFTPARENTHESIS REFSTRING optanchor RIGHTPARENTHESIS
- {
- TikzGraphAssembler *a = [TikzGraphAssembler currentAssembler];
- [a setEdgeTarget:$<nsstr>2
- anchor:$<nsstr>3];
- }
- | selfloop
- {
- TikzGraphAssembler *a = [TikzGraphAssembler currentAssembler];
- [a setEdgeTarget:@""
- anchor:@""];
- };
-selfloop: LEFTPARENTHESIS RIGHTPARENTHESIS;
-
-edgenodecmd: NODE { [[TikzGraphAssembler currentAssembler] prepareNode]; };
+optnoderef:
+ noderef { $$ = $<noderef>1; }
+ | LEFTPARENTHESIS RIGHTPARENTHESIS { $$.node = nil; $$.anchor = nil; }
optedgenode:
- | edgenodecmd optproperties DELIMITEDSTRING
+ { $$ = nil; }
+ | NODE optproperties DELIMITEDSTRING
{
- TikzGraphAssembler *a = [TikzGraphAssembler currentAssembler];
- [[a currentNode] setLabel:$<nsstr>3];
- [a finishNode];
+ $$ = [Node node];
+ [$$ setData:$<data>2];
+ [$$ setLabel:$<nsstr>3];
}
+edge: DRAW_CMD optproperties noderef TO optedgenode optnoderef SEMICOLON
+ {
+ Edge *edge = [Edge edge];
+ [edge setData:$<data>2];
+ [edge setSource:$<noderef>3.node];
+ [edge setSourceAnchor:$<noderef>3.anchor];
+ [edge setEdgeNode:$<node>5];
+ if ($<noderef>6.node) {
+ [edge setTarget:$<noderef>6.node];
+ [edge setTargetAnchor:$<noderef>6.anchor];
+ } else {
+ [edge setTarget:$<noderef>3.node];
+ [edge setTargetAnchor:$<noderef>3.anchor];
+ }
+ [edge setAttributesFromData];
+ [[[TikzGraphAssembler currentAssembler] graph] addEdge:edge];
+ };
ignoreprop: val | val EQUALS val;
ignoreprops: ignoreprop ignoreprops | ;
@@ -154,8 +172,7 @@ optignoreprops: LEFTBRACKET ignoreprops RIGHTBRACKET;
boundingbox:
PATH_CMD optignoreprops COORD RECTANGLE COORD SEMICOLON
{
- Graph *g = [[TikzGraphAssembler currentAssembler] graph];
- [g setBoundingBox:NSRectAroundPoints($<pt>3, $<pt>5)];
+ [[[TikzGraphAssembler currentAssembler] graph] setBoundingBox:NSRectAroundPoints($<pt>3, $<pt>5)];
};
/* vi:ft=yacc:noet:ts=4:sts=4:sw=4