summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Merry <dev@randomguy3.me.uk>2013-03-23 03:30:19 +0000
committerAlex Merry <dev@randomguy3.me.uk>2013-03-23 03:38:55 +0000
commit8cde489ab6c4169fb03d810447c18eea0d0eaa14 (patch)
treead3fcdc71f1819963198ae8a52fc5f2b2818cd20
parente68a44b882e5d6dbbab769f7ef20355ec53a9278 (diff)
Make the parser/lexer reentrant
No more locking! Also, the interface for TikzGraphAssembler is much simpler. Changes to OSX code are completely untested.
-rw-r--r--tikzit/.gitignore1
-rw-r--r--tikzit/src/Makefile.am2
-rw-r--r--tikzit/src/common/TikzGraphAssembler+Parser.h14
-rw-r--r--tikzit/src/common/TikzGraphAssembler.h23
-rw-r--r--tikzit/src/common/TikzGraphAssembler.m243
-rw-r--r--tikzit/src/common/TikzShape.m6
-rw-r--r--tikzit/src/common/tikzlexer.lm114
-rw-r--r--tikzit/src/common/tikzparser.ym30
-rw-r--r--tikzit/src/gtk/TikzDocument.h1
-rw-r--r--tikzit/src/gtk/TikzDocument.m43
-rw-r--r--tikzit/src/gtk/main.m1
-rw-r--r--tikzit/src/osx/AppDelegate.m3
-rw-r--r--tikzit/src/osx/Graph+Coder.m3
-rw-r--r--tikzit/src/osx/GraphicsView.m6
-rw-r--r--tikzit/src/osx/TikzFormatter.m3
-rw-r--r--tikzit/src/osx/TikzSourceController.h3
-rw-r--r--tikzit/src/osx/TikzSourceController.m12
17 files changed, 246 insertions, 262 deletions
diff --git a/tikzit/.gitignore b/tikzit/.gitignore
index 6802e27..644b16b 100644
--- a/tikzit/.gitignore
+++ b/tikzit/.gitignore
@@ -17,6 +17,7 @@ Makefile.in
/missing
/src/tikzit
/src/tikzit.res
+/src/common/tikzlexer.h
/src/common/tikzlexer.m
/src/common/tikzparser.m
/src/common/tikzparser.h
diff --git a/tikzit/src/Makefile.am b/tikzit/src/Makefile.am
index 6ffaa26..e869686 100644
--- a/tikzit/src/Makefile.am
+++ b/tikzit/src/Makefile.am
@@ -127,7 +127,7 @@ common/tikzlexer.m: common/tikzlexer.lm
$(AM_V_GEN)$(LEX) -o $@ $^
common/tikzparser.m: common/tikzparser.ym
- $(AM_V_GEN)$(YACC) --defines=common/tikzparser.h --output=$@ $^
+ $(AM_V_GEN)$(YACC) --output=$@ $^
common/tikzparser.h: common/tikzparser.m
diff --git a/tikzit/src/common/TikzGraphAssembler+Parser.h b/tikzit/src/common/TikzGraphAssembler+Parser.h
index 683e3e2..efceae9 100644
--- a/tikzit/src/common/TikzGraphAssembler+Parser.h
+++ b/tikzit/src/common/TikzGraphAssembler+Parser.h
@@ -25,9 +25,19 @@
#import "TikzGraphAssembler.h"
@interface TikzGraphAssembler (Parser)
+- (Graph*) graph;
/** Store a node so that it can be looked up by name later */
-- (void)addNodeToMap:(Node*)n;
-- (Node*)nodeWithName:(NSString*)name;
+- (void) addNodeToMap:(Node*)n;
+/** Get a previously-stored node by name */
+- (Node*) nodeWithName:(NSString*)name;
+- (void) newLineStarted:(char *)text;
+- (void) incrementPosBy:(size_t)amount;
+- (void) invalidateWithError:(const char *)message;
+- (void*) scanner;
@end
+#define YY_EXTRA_TYPE TikzGraphAssembler *
+#define YYLEX_PARAM [assembler scanner]
+void yyerror(TikzGraphAssembler *assembler, const char *str);
+
// 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 3fc4e9e..16fdf7f 100644
--- a/tikzit/src/common/TikzGraphAssembler.h
+++ b/tikzit/src/common/TikzGraphAssembler.h
@@ -26,24 +26,19 @@
@interface TikzGraphAssembler : NSObject {
Graph *graph;
+ void *scanner;
NSMutableDictionary *nodeMap;
NSError *lastError;
+ char linebuff[500];
+ int lineno;
+ size_t tokenpos;
}
-@property (readonly) Graph *graph;
-@property (readonly) NSError *lastError;
-
-- (BOOL)parseTikz:(NSString*)tikz;
-- (BOOL)parseTikz:(NSString*)tikz forGraph:(Graph*)gr;
-
-- (BOOL)testTikz:(NSString*)tikz;
-
-- (void)invalidate;
-- (void)invalidateWithError:(NSError*)error;
-
-+ (void)setup;
-+ (TikzGraphAssembler*)currentAssembler;
-+ (TikzGraphAssembler*)assembler;
++ (BOOL) parseTikz:(NSString*)tikz forGraph:(Graph*)gr error:(NSError**)e;
++ (BOOL) parseTikz:(NSString*)tikz forGraph:(Graph*)gr;
++ (Graph*) parseTikz:(NSString*)tikz error:(NSError**)e;
++ (Graph*) parseTikz:(NSString*)tikz;
++ (BOOL)validateTikzPropertyNameOrValue:(NSString*)tikz;
@end
diff --git a/tikzit/src/common/TikzGraphAssembler.m b/tikzit/src/common/TikzGraphAssembler.m
index 26bf515..5a01036 100644
--- a/tikzit/src/common/TikzGraphAssembler.m
+++ b/tikzit/src/common/TikzGraphAssembler.m
@@ -22,84 +22,72 @@
//
#import "TikzGraphAssembler.h"
+#import "TikzGraphAssembler+Parser.h"
+#import "tikzparser.h"
+#import "tikzlexer.h"
#import "NSError+Tikzit.h"
-extern int yyparse(void);
-extern int yylex(void);
-extern int yy_scan_string(const char* yy_str);
-extern void yy_delete_buffer(int b);
-extern int yylex_destroy(void);
-
-
-static NSLock *parseLock = nil;
-static id currentAssembler = nil;
-
-extern int yylineno;
-extern int yyleng;
-int lineno;
-int tokenpos;
-extern char *yystr;
-char linebuff[500];
-
-
-void yyerror(const char *str) {
- // if the error is on the first line, treat specially
- if(lineno == 1){
-// strcpy(linebuff, yytext+1);
- NSLog(@"Problem ahoy!");
- }
-
- NSLog(@"Parse error on line %i: %s\n%s\n%@\n", lineno, str, linebuff, [[@"" stringByPaddingToLength:(tokenpos-yyleng) withString: @" " startingAtIndex:0] stringByAppendingString:[@"" stringByPaddingToLength:yyleng withString: @"^" startingAtIndex:0]]);
- if (currentAssembler != nil) {
- NSError *error = [NSError errorWithDomain:@"net.sourceforge.tikzit"
- code:TZ_ERR_PARSE
- userInfo:[NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:[NSString stringWithCString:str encoding:NSUTF8StringEncoding],
- [NSNumber numberWithInt:lineno],
- [NSString stringWithCString:linebuff encoding:NSUTF8StringEncoding],
- [NSNumber numberWithInt:tokenpos],
- [NSNumber numberWithInt:yyleng],
- nil]
- forKeys: [NSArray arrayWithObjects:NSLocalizedDescriptionKey,
- @"lineNumber",
- @"syntaxString",
- @"tokenStart",
- @"tokenLength",
- nil]]];
-
- [currentAssembler invalidateWithError:error];
- }
-}
-
-int yywrap() {
- return 1;
+void yyerror(TikzGraphAssembler *assembler, const char *str) {
+ [assembler invalidateWithError:str];
}
@implementation TikzGraphAssembler
- (id)init {
+ self = nil;
+ return nil;
+}
+
+- (id)initWithGraph:(Graph*)g {
self = [super init];
+ if (self) {
+ graph = [g retain];
+ nodeMap = [[NSMutableDictionary alloc] init];
+ yylex_init (&scanner);
+ yyset_extra(self, scanner);
+ }
return self;
}
- (void)dealloc {
[graph release];
+ [nodeMap release];
[lastError release];
+ yylex_destroy (scanner);
[super dealloc];
}
-- (Graph*)graph { return graph; }
-- (NSError*)lastError { return lastError; }
-
-- (BOOL)parseTikz:(NSString *)tikz {
- return [self parseTikz:tikz forGraph:[Graph graph]];
++ (BOOL) parseTikz:(NSString*)tikz forGraph:(Graph*)gr {
+ return [self parseTikz:tikz forGraph:gr error:NULL];
+}
++ (Graph*) parseTikz:(NSString*)tikz error:(NSError**)e {
+ Graph *gr = [[Graph alloc] init];
+ if ([self parseTikz:tikz forGraph:gr error:e]) {
+ return [gr autorelease];
+ } else {
+ [gr release];
+ return nil;
+ }
+}
++ (Graph*) parseTikz:(NSString*)tikz {
+ return [self parseTikz:tikz error:NULL];
}
-- (BOOL)parseTikz:(NSString*)tikz forGraph:(Graph*)gr {
- [parseLock lock];
-
- lineno = 1;
- tokenpos = 0;
- NSRange range = [tikz rangeOfString:@"\n"];
++ (BOOL) parseTikz:(NSString*)tikz forGraph:(Graph*)gr error:(NSError**)error {
+
+ if([tikz length] == 0) {
+ // empty string -> empty graph
+ return YES;
+ }
+
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ TikzGraphAssembler *assembler = [[self alloc] initWithGraph:gr];
+ [assembler autorelease];
+
+ /*
+ lineno = 1;
+ tokenpos = 0;
+ NSRange range = [tikz rangeOfString:@"\n"];
NSString *firstLine;
if (range.length == 0) {
firstLine = tikz;
@@ -112,49 +100,50 @@ int yywrap() {
// first line too long; just terminate it at the end of the buffer
linebuff[499] = 0;
}
+ */
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- currentAssembler = self;
-
- // set the current graph
- if (graph != gr) {
- [graph release];
- graph = [gr retain];
- }
-
- // the node map keeps track of the mapping of names to nodes
- nodeMap = [[NSMutableDictionary alloc] init];
-
- // do the parsing if actual input
- if([tikz length] > 0){
- yy_scan_string([tikz UTF8String]);
- yyparse();
- yylex_destroy();
- }
-
- [nodeMap release];
- nodeMap = nil;
+ yy_scan_string([tikz UTF8String], [assembler scanner]);
+ int result = yyparse(assembler);
- currentAssembler = nil;
[pool drain];
-
- [parseLock unlock];
-
- return (graph != nil);
+ if (result == 0) {
+ return YES;
+ } else {
+ if (error) {
+ /*
+ if (lastError) {
+ *error = [[lastError retain] autorelease];
+ } else
+ */
+ if (result == 1) {
+ *error = [NSError errorWithMessage:@"Syntax error"
+ code:TZ_ERR_PARSE];
+ } else if (result == 2) {
+ *error = [NSError errorWithMessage:@"Insufficient memory"
+ code:TZ_ERR_PARSE];
+ } else {
+ *error = [NSError errorWithMessage:@"Unknown error"
+ code:TZ_ERR_PARSE];
+ }
+ }
+ return NO;
+ }
}
-- (BOOL)testTikz:(NSString *)tikz{
++ (BOOL)validateTikzPropertyNameOrValue:(NSString*)tikz {
BOOL r;
NSString * testTikz = [NSString stringWithFormat: @"{%@}", tikz];
- yy_scan_string([testTikz UTF8String]);
- yylex();
-
- r = !(yyleng < [testTikz length]);
-
+ void *scanner;
+ yylex_init (&scanner);
+ yyset_extra(nil, scanner);
+ yy_scan_string([testTikz UTF8String], scanner);
+ YYSTYPE lval;
+ yylex(&lval, scanner);
+ r = !(yyget_leng(scanner) < [testTikz length]);
+ yylex_destroy(scanner);
[testTikz autorelease];
- yylex_destroy();
return r;
}
@@ -165,32 +154,66 @@ int yywrap() {
lastError = nil;
}
-- (void)invalidateWithError:(NSError*)error {
- [self invalidate];
- lastError = [error retain];
-}
-
-+ (void)setup {
- parseLock = [[NSLock alloc] init];
-}
-
-+ (TikzGraphAssembler*)currentAssembler {
- return currentAssembler;
-}
-
-+ (TikzGraphAssembler*)assembler {
- return [[[TikzGraphAssembler alloc] init] autorelease];
-}
-
@end
@implementation TikzGraphAssembler (Parser)
+- (Graph*)graph { return graph; }
- (void)addNodeToMap:(Node*)n {
[nodeMap setObject:n forKey:[n name]];
}
- (Node*)nodeWithName:(NSString*)name {
- return [nodeMap objectForKey:name];
+ return [nodeMap objectForKey:name];
+}
+- (void) newLineStarted:(char *)text {
+ /*
+ strncpy(linebuff, yytext+1, 500);
+ linebuff[499] = 0; // ensure null-terminated
+ lineno++;
+ tokenpos = 0;
+ */
+}
+- (void) incrementPosBy:(size_t)amount {
+ //tokenpos += amount;
+}
+
+- (void) invalidateWithError:(const char *)message {
+ /*
+ // if the error is on the first line, treat specially
+ if([assembler lineNumber] == 1){
+ //strcpy(linebuff, yytext+1);
+ NSLog(@"Problem ahoy!");
+ }
+
+ NSString *pointerStrPad = [@"" stringByPaddingToLength:(tokenpos-yyleng)
+ withString:@" "
+ startingAtIndex:0];
+ NSString *pointerStr = [@"" stringByPaddingToLength:yyleng
+ withString:@"^"
+ startingAtIndex:0];
+ NSLog(@"Parse error on line %i: %s\n%s\n%@\n", lineno, str, linebuff,
+ [pointerStrPad stringByAppendingString:pointerStr]);
+ NSDictionary *userInfo =
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSString stringWithUTF8String:str],
+ NSLocalizedDescriptionKey,
+ [NSNumber numberWithInt:lineno],
+ @"lineNumber",
+ [NSString stringWithUTF8String:linebuff],
+ @"syntaxString",
+ [NSNumber numberWithInt:tokenpos],
+ @"tokenStart",
+ [NSNumber numberWithInt:yyleng],
+ @"tokenLength"];
+ NSError *error =
+ [NSError errorWithDomain:@"net.sourceforge.tikzit"
+ code:TZ_ERR_PARSE
+ userInfo:userInfo];
+
+ lastError = [error retain];
+ */
+ [self invalidate];
}
+- (void*) scanner { return scanner; }
@end
// vi:ft=objc:ts=4:noet:sts=4:sw=4
diff --git a/tikzit/src/common/TikzShape.m b/tikzit/src/common/TikzShape.m
index b5b23c3..722275c 100644
--- a/tikzit/src/common/TikzShape.m
+++ b/tikzit/src/common/TikzShape.m
@@ -35,11 +35,7 @@
error:NULL];
if (tikz == nil) return nil;
- TikzGraphAssembler *ass = [[TikzGraphAssembler alloc] init];
- [ass parseTikz:tikz];
-
- Graph *graph = [ass graph];
- [ass release];
+ Graph *graph = [TikzGraphAssembler parseTikz:tikz];
if (graph == nil) return nil;
NSRect graphBounds = ([graph hasBoundingBox]) ? [graph boundingBox] : [graph bounds];
diff --git a/tikzit/src/common/tikzlexer.lm b/tikzit/src/common/tikzlexer.lm
index ad99445..3e2e0ed 100644
--- a/tikzit/src/common/tikzlexer.lm
+++ b/tikzit/src/common/tikzlexer.lm
@@ -1,11 +1,3 @@
-%option nounput
-%option yylineno
-%s props
-%s xcoord
-%s ycoord
-%s noderef
-FLOAT \-?[0-9]*(\.[0-9]+)?
-
%{
/*
* Copyright 2010 Chris Heunen
@@ -28,96 +20,100 @@ FLOAT \-?[0-9]*(\.[0-9]+)?
*/
#import <Foundation/Foundation.h>
-#ifdef __APPLE__
-#include "y.tab.h"
-#else
-#include "tikzparser.h"
-#endif
-
-extern char linebuff[500];
-extern int lineno;
-extern int tokenpos;
+#import "tikzparser.h"
%}
+
+%option reentrant bison-bridge 8bit
+%option nounput
+%option yylineno
+%option noyywrap
+%option header-file="common/tikzlexer.h"
+
+%s props
+%s xcoord
+%s ycoord
+%s noderef
+
+FLOAT \-?[0-9]*(\.[0-9]+)?
+
%%
-%\n /* ignore end of line */;
-\n.* { strncpy(linebuff, yytext+1, 500);
- linebuff[499] = 0; // ensure null-terminated
- lineno++;
- tokenpos = 0;
- yyless(1);
- }
-<INITIAL,xcoord,ycoord,props,noderef>[ ]+ { tokenpos += yyleng; } /* ignore whitespace */;
-<INITIAL,xcoord,ycoord,props,noderef>[\t]+ { tokenpos += 8*yyleng; } /* ignore whitespace */;
-\\begin\{tikzpicture\} { tokenpos += yyleng; return BEGIN_TIKZPICTURE_CMD; }
-\\end\{tikzpicture\} { tokenpos += yyleng; return END_TIKZPICTURE_CMD; }
-\\begin\{pgfonlayer\} { tokenpos += yyleng; return BEGIN_PGFONLAYER_CMD; }
-\\end\{pgfonlayer\} { tokenpos += yyleng; return END_PGFONLAYER_CMD; }
-\\draw { tokenpos += yyleng; return DRAW_CMD; }
-\\node { tokenpos += yyleng; return NODE_CMD; }
-\\path { tokenpos += yyleng; return PATH_CMD; }
-rectangle { tokenpos += yyleng; return RECTANGLE; }
-node { tokenpos += yyleng; return NODE; }
-at { tokenpos += yyleng; return AT; }
-to { tokenpos += yyleng; return TO; }
-; { tokenpos += yyleng; return SEMICOLON; }
+
+\n.* {
+ [yyextra newLineStarted:yytext+1];
+ yyless(1);
+}
+<INITIAL,xcoord,ycoord,props,noderef>[ ]+ { [yyextra incrementPosBy:yyleng]; } /* ignore whitespace */;
+<INITIAL,xcoord,ycoord,props,noderef>[\t]+ { [yyextra incrementPosBy:8*yyleng]; } /* ignore whitespace */;
+\\begin\{tikzpicture\} { [yyextra incrementPosBy:yyleng]; return BEGIN_TIKZPICTURE_CMD; }
+\\end\{tikzpicture\} { [yyextra incrementPosBy:yyleng]; return END_TIKZPICTURE_CMD; }
+\\begin\{pgfonlayer\} { [yyextra incrementPosBy:yyleng]; return BEGIN_PGFONLAYER_CMD; }
+\\end\{pgfonlayer\} { [yyextra incrementPosBy:yyleng]; return END_PGFONLAYER_CMD; }
+\\draw { [yyextra incrementPosBy:yyleng]; return DRAW_CMD; }
+\\node { [yyextra incrementPosBy:yyleng]; return NODE_CMD; }
+\\path { [yyextra incrementPosBy:yyleng]; return PATH_CMD; }
+rectangle { [yyextra incrementPosBy:yyleng]; return RECTANGLE; }
+node { [yyextra incrementPosBy:yyleng]; return NODE; }
+at { [yyextra incrementPosBy:yyleng]; return AT; }
+to { [yyextra incrementPosBy:yyleng]; return TO; }
+; { [yyextra incrementPosBy:yyleng]; return SEMICOLON; }
\([ ]*{FLOAT}[ ]*,[ ]*{FLOAT}[ ]*\) {
- tokenpos += 1;
+ [yyextra incrementPosBy:1];
yyless(1);
BEGIN(xcoord);
}
<xcoord>{FLOAT} {
- tokenpos += yyleng;
- yylval.pt.x=(float)strtod(yytext,NULL);
+ [yyextra incrementPosBy:yyleng];
+ yylval->pt.x=(float)strtod(yytext,NULL);
BEGIN(ycoord);
}
-<ycoord>, { tokenpos += yyleng; }
+<ycoord>, { [yyextra incrementPosBy:yyleng]; }
<ycoord>{FLOAT} {
- tokenpos += yyleng;
- yylval.pt.y=(float)strtod(yytext,NULL);
+ [yyextra incrementPosBy:yyleng];
+ yylval->pt.y=(float)strtod(yytext,NULL);
}
<ycoord>\) {
- tokenpos += yyleng;
+ [yyextra incrementPosBy:yyleng];
BEGIN(INITIAL);
return COORD;
}
/* when we see "[", change parsing mode */
\[ /*syntaxhlfix]*/ {
- tokenpos += yyleng;
+ [yyextra incrementPosBy:yyleng];
BEGIN(props);
return LEFTBRACKET;
}
-<props>= { tokenpos += yyleng; return EQUALS; }
-<props>, { tokenpos += yyleng; return COMMA; }
+<props>= { [yyextra incrementPosBy:yyleng]; return EQUALS; }
+<props>, { [yyextra incrementPosBy:yyleng]; return COMMA; }
<props>[^=,\{\] \t]([^=,\{\]]*[^=,\{\] \t])? {
- tokenpos += yyleng;
- yylval.nsstr=[NSString stringWithUTF8String:yytext];
+ [yyextra incrementPosBy:yyleng];
+ yylval->nsstr=[NSString stringWithUTF8String:yytext];
return PROPSTRING;
}
<props>\] {
- tokenpos += yyleng;
+ [yyextra incrementPosBy:yyleng];
BEGIN(INITIAL);
return RIGHTBRACKET;
}
\( {
- tokenpos += yyleng;
+ [yyextra incrementPosBy:yyleng];
BEGIN(noderef);
return LEFTPARENTHESIS;
}
<noderef>\. {
- tokenpos += yyleng;
+ [yyextra incrementPosBy:yyleng];
return FULLSTOP;
}
<noderef>[^\.\{\)]+ {
- tokenpos += yyleng;
- yylval.nsstr=[NSString stringWithUTF8String:yytext];
+ [yyextra incrementPosBy:yyleng];
+ yylval->nsstr=[NSString stringWithUTF8String:yytext];
return REFSTRING;
}
<noderef>\) {
- tokenpos += yyleng;
+ [yyextra incrementPosBy:yyleng];
BEGIN(INITIAL);
return RIGHTPARENTHESIS;
}
@@ -127,7 +123,7 @@ to { tokenpos += yyleng; return TO; }
unsigned int brace_depth = 1;
unsigned int escape = 0;
while (1) {
- char c = input();
+ char c = input(yyscanner);
// eof reached before closing brace
if (c == '\0' || c == EOF) yyterminate();
@@ -147,8 +143,8 @@ to { tokenpos += yyleng; return TO; }
NSString *s = [buf copy];
yyleng += 1 + [buf length];
[s autorelease];
- yylval.nsstr = s;
- tokenpos += yyleng;
+ yylval->nsstr = s;
+ [yyextra incrementPosBy:yyleng];
return DELIMITEDSTRING;
}
diff --git a/tikzit/src/common/tikzparser.ym b/tikzit/src/common/tikzparser.ym
index 074ec2d..1183f12 100644
--- a/tikzit/src/common/tikzparser.ym
+++ b/tikzit/src/common/tikzparser.ym
@@ -1,5 +1,3 @@
-%error-verbose
-
%{
/*
* Copyright 2010 Chris Heunen
@@ -21,18 +19,12 @@
* 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;
-extern int yylex(void);
-extern void yyerror(const char *str);
-
%}
%code requires {
+#import "TikzGraphAssembler+Parser.h"
#import "GraphElementData.h"
#import "GraphElementProperty.h"
#import "Node.h"
@@ -42,6 +34,12 @@ struct noderef {
};
}
+%defines "common/tikzparser.h"
+%pure-parser
+%parse-param {TikzGraphAssembler *assembler}
+%error-verbose
+
+
%union {
NSPoint pt;
NSString *nsstr;
@@ -51,6 +49,10 @@ struct noderef {
struct noderef noderef;
};
+%{
+#import "tikzlexer.h"
+%}
+
%token BEGIN_TIKZPICTURE_CMD "\\begin{tikzpicture}"
%token END_TIKZPICTURE_CMD "\\end{tikzpicture}"
@@ -127,14 +129,14 @@ node: "\\node" optproperties nodename "at" COORD DELIMITEDSTRING ";"
[node setName:$3];
[node setPoint:$5];
[node setLabel:$6];
- [[TikzGraphAssembler currentAssembler] addNodeToMap:node];
- [[[TikzGraphAssembler currentAssembler] graph] addNode:node];
+ [assembler addNodeToMap:node];
+ [[assembler graph] addNode:node];
};
optanchor: { $$ = nil; } | "." REFSTRING { $$ = $2; };
noderef: "(" REFSTRING optanchor ")"
{
- $$.node = [[TikzGraphAssembler currentAssembler] nodeWithName:$2];
+ $$.node = [assembler nodeWithName:$2];
$$.anchor = $3;
};
optnoderef:
@@ -163,7 +165,7 @@ edge: "\\draw" optproperties noderef "to" optedgenode optnoderef ";"
[edge setTargetAnchor:$3.anchor];
}
[edge setAttributesFromData];
- [[[TikzGraphAssembler currentAssembler] graph] addEdge:edge];
+ [[assembler graph] addEdge:edge];
};
ignoreprop: val | val "=" val;
@@ -172,7 +174,7 @@ optignoreprops: "[" ignoreprops "]";
boundingbox:
"\\path" optignoreprops COORD "rectangle" COORD ";"
{
- [[[TikzGraphAssembler currentAssembler] graph] setBoundingBox:NSRectAroundPoints($3, $5)];
+ [[assembler graph] setBoundingBox:NSRectAroundPoints($3, $5)];
};
/* vi:ft=yacc:noet:ts=4:sts=4:sw=4
diff --git a/tikzit/src/gtk/TikzDocument.h b/tikzit/src/gtk/TikzDocument.h
index da73fac..2b55f05 100644
--- a/tikzit/src/gtk/TikzDocument.h
+++ b/tikzit/src/gtk/TikzDocument.h
@@ -70,7 +70,6 @@
@property (readonly) NSString *undoName;
@property (readonly) NSString *redoName;
-- (BOOL) validateTikz:(NSString**)tikz error:(NSError**)error;
- (BOOL) updateTikz:(NSString*)t error:(NSError**)error;
- (Graph*) cutSelection;
diff --git a/tikzit/src/gtk/TikzDocument.m b/tikzit/src/gtk/TikzDocument.m
index 30d604a..78746f2 100644
--- a/tikzit/src/gtk/TikzDocument.m
+++ b/tikzit/src/gtk/TikzDocument.m
@@ -256,26 +256,6 @@
return tikz;
}
-- (BOOL) validateTikz:(NSString**)t error:(NSError**)error {
- if (*t == nil) {
- return NO;
- }
- if (*t == tikz || [*t isEqual:tikz]) {
- return YES;
- }
-
- TikzGraphAssembler *a = [TikzGraphAssembler assembler];
- BOOL success = [a parseTikz:*t];
- if (!success && error != NULL) {
- *error = [a lastError];
- if (*error == nil) {
- *error = [NSError errorWithMessage:@"Unknown error"
- code:TZ_ERR_PARSE];
- }
- }
- return success;
-}
-
- (BOOL) updateTikz:(NSString*)t error:(NSError**)error {
if (t == nil) {
t = [NSString string];
@@ -284,25 +264,17 @@
return YES;
}
- TikzGraphAssembler *a = [TikzGraphAssembler assembler];
- BOOL success = [a parseTikz:t];
- if (success) {
+ Graph *g = [TikzGraphAssembler parseTikz:t error:error];
+ if (g) {
// updateTikz actually generates a graph from the tikz,
// and generates the final tikz from that
[self startUndoGroup];
- [self setGraph:[a graph]];
+ [self setGraph:g];
[self nameAndEndUndoGroup:@"Update tikz"];
- } else {
- if (error != NULL) {
- *error = [a lastError];
- if (*error == nil) {
- *error = [NSError errorWithMessage:@"Unknown error"
- code:TZ_ERR_PARSE];
- }
- }
+ return YES;
}
- return success;
+ return NO;
}
- (Graph*) cutSelection {
@@ -338,9 +310,8 @@
}
- (void) pasteFromTikz:(NSString*)t {
- TikzGraphAssembler *a = [TikzGraphAssembler assembler];
- if ([a parseTikz:t]) {
- Graph *clipboard = [a graph];
+ Graph *clipboard = [TikzGraphAssembler parseTikz:t];
+ if (clipboard) {
[self attachStylesToGraph:clipboard];
[self paste:clipboard];
}
diff --git a/tikzit/src/gtk/main.m b/tikzit/src/gtk/main.m
index eb06449..10fa990 100644
--- a/tikzit/src/gtk/main.m
+++ b/tikzit/src/gtk/main.m
@@ -81,7 +81,6 @@ int main (int argc, char *argv[]) {
tz_register_stock_items();
clipboard_init();
- [TikzGraphAssembler setup];
Application *app = nil;
if (argc > 1) {
diff --git a/tikzit/src/osx/AppDelegate.m b/tikzit/src/osx/AppDelegate.m
index 87d3ae0..affb95c 100644
--- a/tikzit/src/osx/AppDelegate.m
+++ b/tikzit/src/osx/AppDelegate.m
@@ -22,7 +22,6 @@
//
#import "AppDelegate.h"
-#import "TikzGraphAssembler.h"
#import "TikzDocument.h"
#import "Shape.h"
#import "SupportDir.h"
@@ -36,8 +35,6 @@
}
- (void)awakeFromNib {
- [TikzGraphAssembler setup]; // initialise lex/yacc parser globals
-
[SupportDir createUserSupportDir];
NSString *supportDir = [SupportDir userSupportDir];
//NSLog(stylePlist);
diff --git a/tikzit/src/osx/Graph+Coder.m b/tikzit/src/osx/Graph+Coder.m
index 6a3f650..7d3787e 100644
--- a/tikzit/src/osx/Graph+Coder.m
+++ b/tikzit/src/osx/Graph+Coder.m
@@ -13,8 +13,7 @@
- (id)initWithCoder:(NSCoder*)coder {
NSString *tikz = [coder decodeObject];
- TikzGraphAssembler *ass = [[TikzGraphAssembler alloc] init];
- [ass parseTikz:tikz forGraph:self];
+ [TikzGraphAssembler parseTikz:tikz forGraph:self];
return self;
}
diff --git a/tikzit/src/osx/GraphicsView.m b/tikzit/src/osx/GraphicsView.m
index d5d6186..49b1af6 100644
--- a/tikzit/src/osx/GraphicsView.m
+++ b/tikzit/src/osx/GraphicsView.m
@@ -1099,11 +1099,9 @@ static CGColorRef cgGrayColor, cgWhiteColor, cgClearColor = nil;
NSData *data = [cb dataForType:type];
NSString *tikz = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
//NSLog(@"pasting tikz:\n%@",tikz);
- TikzGraphAssembler *ass = [[TikzGraphAssembler alloc] init];
- if ([ass parseTikz:tikz]) {
+ Graph *clip = [TikzGraphAssembler parseTikz:tikz];
+ if (clip) {
//NSLog(@"tikz pasted:\n%@",tikz);
- Graph *clip = [ass graph];
-
NSRect graphBounds = [graph bounds];
NSRect clipBounds = [clip bounds];
float dx = graphBounds.origin.x +
diff --git a/tikzit/src/osx/TikzFormatter.m b/tikzit/src/osx/TikzFormatter.m
index ecbb0bc..8972706 100644
--- a/tikzit/src/osx/TikzFormatter.m
+++ b/tikzit/src/osx/TikzFormatter.m
@@ -38,8 +38,7 @@
- (BOOL)getObjectValue:(out id *)obj forString:(NSString *)string errorDescription:(out NSString **)error{
*obj = [NSString stringWithString:string];
- TikzGraphAssembler *ass = [[TikzGraphAssembler alloc] init];
- BOOL r = [ass testTikz:string];
+ BOOL r = [TikzGraphAssembler validateTikzPropertyNameOrValue:string];
if (!r && error)
*error = NSLocalizedString(@"Invalid input, couldn't parse value.", @"tikz user input error");
diff --git a/tikzit/src/osx/TikzSourceController.h b/tikzit/src/osx/TikzSourceController.h
index c829336..3408d9f 100644
--- a/tikzit/src/osx/TikzSourceController.h
+++ b/tikzit/src/osx/TikzSourceController.h
@@ -24,7 +24,6 @@
#import <Cocoa/Cocoa.h>
#import "GraphicsView.h"
-#import "TikzGraphAssembler.h"
#import "ParseErrorView.h"
@interface TikzSourceController : NSObject {
@@ -43,7 +42,7 @@
BOOL tikzChanged;
BOOL justUndid;
- TikzGraphAssembler *assembler;
+ NSError *lastError;
}
@property BOOL tikzChanged;
diff --git a/tikzit/src/osx/TikzSourceController.m b/tikzit/src/osx/TikzSourceController.m
index d05aa41..d01589b 100644
--- a/tikzit/src/osx/TikzSourceController.m
+++ b/tikzit/src/osx/TikzSourceController.m
@@ -22,6 +22,7 @@
//
#import "TikzSourceController.h"
+#import "TikzGraphAssembler.h"
#import "Graph.h"
@implementation TikzSourceController
@@ -82,8 +83,6 @@
- (void)awakeFromNib {
justUndid = NO;
- assembler = [[TikzGraphAssembler alloc] init];
-
successColor = [NSColor colorWithCalibratedRed:0.0f
green:0.5f
blue:0.0f
@@ -143,11 +142,12 @@
}
- (BOOL)tryParseTikz {
- BOOL success = [assembler parseTikz:[self tikz]];
+ Graph *g = [TikzGraphAssembler parseTikz:[self tikz]
+ error:&lastError];
- if (success) {
+ if (g) {
[graphicsView deselectAll:self];
- [graphicsView setGraph:[assembler graph]];
+ [graphicsView setGraph:g];
[graphicsView refreshLayers];
[self doRevertTikz];
}
@@ -181,7 +181,7 @@
[status setStringValue:@"parse error"];
[status setTextColor:failedColor];
- NSDictionary *d = [[assembler lastError] userInfo];
+ NSDictionary *d = [lastError userInfo];
NSString *ts = [NSString stringWithFormat: @"Parse error on line %@: %@\n", [d valueForKey:@"lineNumber"], [d valueForKey:NSLocalizedDescriptionKey]];
NSMutableAttributedString *as = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat: @"Parse error on line %@: %@\n%@\n", [d valueForKey:@"lineNumber"], [d valueForKey:NSLocalizedDescriptionKey], [[d valueForKey:@"syntaxString"] stringByReplacingOccurrencesOfString:@"\t" withString:@""]]];