From 8cde489ab6c4169fb03d810447c18eea0d0eaa14 Mon Sep 17 00:00:00 2001 From: Alex Merry Date: Sat, 23 Mar 2013 03:30:19 +0000 Subject: Make the parser/lexer reentrant No more locking! Also, the interface for TikzGraphAssembler is much simpler. Changes to OSX code are completely untested. --- tikzit/.gitignore | 1 + tikzit/src/Makefile.am | 2 +- tikzit/src/common/TikzGraphAssembler+Parser.h | 14 +- tikzit/src/common/TikzGraphAssembler.h | 23 +-- tikzit/src/common/TikzGraphAssembler.m | 243 ++++++++++++++------------ tikzit/src/common/TikzShape.m | 6 +- tikzit/src/common/tikzlexer.lm | 114 ++++++------ tikzit/src/common/tikzparser.ym | 30 ++-- tikzit/src/gtk/TikzDocument.h | 1 - tikzit/src/gtk/TikzDocument.m | 43 +---- tikzit/src/gtk/main.m | 1 - tikzit/src/osx/AppDelegate.m | 3 - tikzit/src/osx/Graph+Coder.m | 3 +- tikzit/src/osx/GraphicsView.m | 6 +- tikzit/src/osx/TikzFormatter.m | 3 +- tikzit/src/osx/TikzSourceController.h | 3 +- tikzit/src/osx/TikzSourceController.m | 12 +- 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 -#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); - } -[ ]+ { tokenpos += yyleng; } /* ignore whitespace */; -[\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); +} +[ ]+ { [yyextra incrementPosBy:yyleng]; } /* ignore whitespace */; +[\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); } {FLOAT} { - tokenpos += yyleng; - yylval.pt.x=(float)strtod(yytext,NULL); + [yyextra incrementPosBy:yyleng]; + yylval->pt.x=(float)strtod(yytext,NULL); BEGIN(ycoord); } -, { tokenpos += yyleng; } +, { [yyextra incrementPosBy:yyleng]; } {FLOAT} { - tokenpos += yyleng; - yylval.pt.y=(float)strtod(yytext,NULL); + [yyextra incrementPosBy:yyleng]; + yylval->pt.y=(float)strtod(yytext,NULL); } \) { - 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; } -= { tokenpos += yyleng; return EQUALS; } -, { tokenpos += yyleng; return COMMA; } += { [yyextra incrementPosBy:yyleng]; return EQUALS; } +, { [yyextra incrementPosBy:yyleng]; return COMMA; } [^=,\{\] \t]([^=,\{\]]*[^=,\{\] \t])? { - tokenpos += yyleng; - yylval.nsstr=[NSString stringWithUTF8String:yytext]; + [yyextra incrementPosBy:yyleng]; + yylval->nsstr=[NSString stringWithUTF8String:yytext]; return PROPSTRING; } \] { - tokenpos += yyleng; + [yyextra incrementPosBy:yyleng]; BEGIN(INITIAL); return RIGHTBRACKET; } \( { - tokenpos += yyleng; + [yyextra incrementPosBy:yyleng]; BEGIN(noderef); return LEFTPARENTHESIS; } \. { - tokenpos += yyleng; + [yyextra incrementPosBy:yyleng]; return FULLSTOP; } [^\.\{\)]+ { - tokenpos += yyleng; - yylval.nsstr=[NSString stringWithUTF8String:yytext]; + [yyextra incrementPosBy:yyleng]; + yylval->nsstr=[NSString stringWithUTF8String:yytext]; return REFSTRING; } \) { - 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 . */ -#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 #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:@""]]]; -- cgit v1.2.3