summaryrefslogtreecommitdiff
path: root/tikzit/src/common
diff options
context:
space:
mode:
authorJohan Paulsson <gonz@users.sourceforge.net>2013-01-27 16:54:57 +0000
committerJohan Paulsson <gonz@users.sourceforge.net>2013-01-27 16:54:57 +0000
commitd35a186932e95b979bb947110a2e7d2cca41fcc9 (patch)
treec01417f00717afd223a9a2052cfaa809e8de655e /tikzit/src/common
parent46d894569372dea8c3e3f698b361f68d6bbebde6 (diff)
Better parser errors on syntax errors. Will show line number, description and where the error happened.
Test function for delimited string if they will break reprising.
Diffstat (limited to 'tikzit/src/common')
-rw-r--r--tikzit/src/common/TikzGraphAssembler.h2
-rw-r--r--tikzit/src/common/TikzGraphAssembler.m44
-rw-r--r--tikzit/src/common/tikzlexer.lm60
-rw-r--r--tikzit/src/common/tikzparser.ym3
4 files changed, 81 insertions, 28 deletions
diff --git a/tikzit/src/common/TikzGraphAssembler.h b/tikzit/src/common/TikzGraphAssembler.h
index adaf443..a0c8a0d 100644
--- a/tikzit/src/common/TikzGraphAssembler.h
+++ b/tikzit/src/common/TikzGraphAssembler.h
@@ -41,6 +41,8 @@
- (BOOL)parseTikz:(NSString*)tikz;
- (BOOL)parseTikz:(NSString*)tikz forGraph:(Graph*)gr;
+- (BOOL)testTikz:(NSString*)tikz;
+
- (void)prepareNode;
- (void)finishNode;
diff --git a/tikzit/src/common/TikzGraphAssembler.m b/tikzit/src/common/TikzGraphAssembler.m
index 7d8d0e7..050b5fe 100644
--- a/tikzit/src/common/TikzGraphAssembler.m
+++ b/tikzit/src/common/TikzGraphAssembler.m
@@ -34,8 +34,16 @@ extern int yylex_destroy(void);
static NSLock *parseLock = nil;
static id currentAssembler = nil;
+int yylineno;
+int yyleng;
+int lineno;
+int tokenpos;
+char *yystr;
+char linebuff[500];
+
+
void yyerror(const char *str) {
- NSLog(@"Parse error: %s", str);
+ 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
@@ -81,6 +89,10 @@ int yywrap() {
- (BOOL)parseTikz:(NSString*)tikz forGraph:(Graph*)gr {
[parseLock lock];
+
+ lineno = 1;
+ tokenpos = 0;
+ linebuff[0] = 0;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
currentAssembler = self;
@@ -93,12 +105,14 @@ int yywrap() {
// the node map keeps track of the mapping of names to nodes
nodeMap = [[NSMutableDictionary alloc] init];
-
- // do the parsing
- yy_scan_string([tikz UTF8String]);
- yyparse();
- yylex_destroy();
-
+
+ // do the parsing if actual input
+ if([tikz length] > 0){
+ yy_scan_string([tikz UTF8String]);
+ yyparse();
+ yylex_destroy();
+ }
+
[nodeMap release];
nodeMap = nil;
@@ -110,6 +124,22 @@ int yywrap() {
return (graph != nil);
}
+- (BOOL)testTikz:(NSString *)tikz{
+ BOOL r;
+
+ NSString * testTikz = [NSString stringWithFormat: @"{%@}", tikz];
+
+ yy_scan_string([testTikz UTF8String]);
+ yylex();
+
+ r = !(yyleng < [testTikz length]);
+
+ [testTikz autorelease];
+ yylex_destroy();
+
+ return r;
+}
+
- (void)prepareNode {
currentNode = [[Node alloc] init];
}
diff --git a/tikzit/src/common/tikzlexer.lm b/tikzit/src/common/tikzlexer.lm
index 9af0c8d..8f34ace 100644
--- a/tikzit/src/common/tikzlexer.lm
+++ b/tikzit/src/common/tikzlexer.lm
@@ -1,4 +1,6 @@
%option nounput
+%option yylineno
+
%{
//
// tikzparser.l
@@ -30,48 +32,62 @@
#include "tikzparser.h"
#endif
+extern char linebuff[500];
+extern int lineno;
+extern yy_size_t yyleng;
+extern int tokenpos;
%}
%%
-\n /* ignore end of line */;
-[ \t]+ /* ignore whitespace */;
-\\begin return LATEXBEGIN;
-\\end return LATEXEND;
-\{tikzpicture\} return TIKZPICTURE;
-\{pgfonlayer\} return PGFONLAYER;
-\( return LEFTPARENTHESIS;
-\) return RIGHTPARENTHESIS;
-\[ return LEFTBRACKET;
-\] return RIGHTBRACKET;
-; return SEMICOLON;
-, return COMMA;
-\. return FULLSTOP;
-= return EQUALS;
-\\draw return DRAW;
-to return TO;
-\\node return NODE;
-\\path return PATH;
-node return ALTNODE;
-rectangle return RECTANGLE;
-at return AT;
+%\n /* ignore end of line */;
+\n.* { strcpy(linebuff, yytext+1);
+ lineno++;
+ tokenpos = 0;
+ yyless(1);
+ }
+[ ]+ { tokenpos += yyleng; } /* ignore whitespace */;
+[\t]+ { tokenpos += 4*yyleng; } /* ignore whitespace */;
+\\begin { tokenpos += yyleng; return LATEXBEGIN; }
+\\end { tokenpos += yyleng; return LATEXEND; }
+\{tikzpicture\} { tokenpos += yyleng; return TIKZPICTURE; }
+\{pgfonlayer\} { tokenpos += yyleng; return PGFONLAYER; }
+\( { tokenpos += yyleng; return LEFTPARENTHESIS; }
+\) { tokenpos += yyleng; return RIGHTPARENTHESIS; }
+\[ { tokenpos += yyleng; return LEFTBRACKET; }
+\] { tokenpos += yyleng; return RIGHTBRACKET; }
+; { tokenpos += yyleng; return SEMICOLON; }
+, { tokenpos += yyleng; return COMMA; }
+\. { tokenpos += yyleng; return FULLSTOP; }
+= { tokenpos += yyleng; return EQUALS; }
+\\draw { tokenpos += yyleng; return DRAW; }
+to { tokenpos += yyleng; return TO; }
+\\node { tokenpos += yyleng; return NODE; }
+\\path { tokenpos += yyleng; return PATH; }
+node { tokenpos += yyleng; return ALTNODE; }
+rectangle { tokenpos += yyleng; return RECTANGLE; }
+at { tokenpos += yyleng; return AT; }
[0-9]+ {
+ tokenpos += yyleng;
yylval.nsstr=[NSString stringWithUTF8String:yytext];
return NATURALNUMBER;
}
(\-?[0-9]*\.[0-9]+)|(\-?[0-9]+) {
+ tokenpos += yyleng;
yylval.nsstr=[NSString stringWithUTF8String:yytext];
return REALNUMBER;
}
\\?[a-zA-Z<>\-\'][a-zA-Z<>\-\'0-9]* { //'
+ tokenpos += yyleng;
yylval.nsstr=[NSString stringWithUTF8String:yytext];
return LWORD;
}
\"[^\"]*\" /* " */ {
+ tokenpos += yyleng;
yylval.nsstr=[NSString stringWithUTF8String:yytext];
return QUOTEDSTRING;
}
@@ -93,8 +109,10 @@ at return AT;
}
NSString *s = [buf copy];
+ yyleng += 1 + [buf length];
[s autorelease];
yylval.nsstr = s;
+ tokenpos += yyleng;
return DELIMITEDSTRING;
}
diff --git a/tikzit/src/common/tikzparser.ym b/tikzit/src/common/tikzparser.ym
index 532b6c8..487cfd4 100644
--- a/tikzit/src/common/tikzparser.ym
+++ b/tikzit/src/common/tikzparser.ym
@@ -29,6 +29,9 @@
#import "TikzGraphAssembler.h"
#import "GraphElementProperty.h"
+extern char* yystr;
+extern int yylineno;
+extern int tokenpos;
extern int yylex(void);
extern void yyerror(const char *str);