diff options
Diffstat (limited to 'tikzit-old/src/common/tikzparser.ym')
-rw-r--r-- | tikzit-old/src/common/tikzparser.ym | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/tikzit-old/src/common/tikzparser.ym b/tikzit-old/src/common/tikzparser.ym new file mode 100644 index 0000000..344e969 --- /dev/null +++ b/tikzit-old/src/common/tikzparser.ym @@ -0,0 +1,224 @@ +%{ +/* + * 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 "tikzparserdefs.h" +%} + +/* we use features added to bison 2.4 */ +%require "2.3" + +%error-verbose +/* enable maintaining locations for better error messages */ +%locations +/* the name of the header file */ +/*%defines "common/tikzparser.h"*/ +/* make it re-entrant (no global variables) */ +%pure-parser +/* We use a pure (re-entrant) lexer. This means yylex + will take a void* (opaque) type to maintain its state */ +%lex-param {void *scanner} +/* Since this parser is also pure, yyparse needs to take + that lexer state as an argument */ +%parse-param {void *scanner} + +/* possible data types for semantic values */ +%union { + NSString *nsstr; + GraphElementProperty *prop; + GraphElementData *data; + Node *node; + NSPoint pt; + struct noderef noderef; +} + +%{ +#import "GraphElementData.h" +#import "GraphElementProperty.h" +#import "Node.h" +#import "Edge.h" + +#import "tikzlexer.h" +#import "TikzGraphAssembler+Parser.h" +/* the assembler (used by this parser) is stored in the lexer + state as "extra" data */ +#define assembler yyget_extra(scanner) + +/* pass errors off to the assembler */ +void yyerror(YYLTYPE *yylloc, void *scanner, const char *str) { + [assembler reportError:str atLocation:yylloc]; +} +%} + +/* yyloc is set up with first_column = last_column = 1 by default; + however, it makes more sense to think of us being "before the + start of the line" before we parse anything */ +%initial-action { + yylloc.first_column = yylloc.last_column = 0; +} + + +%token BEGIN_TIKZPICTURE_CMD "\\begin{tikzpicture}" +%token END_TIKZPICTURE_CMD "\\end{tikzpicture}" +%token BEGIN_PGFONLAYER_CMD "\\begin{pgfonlayer}" +%token END_PGFONLAYER_CMD "\\end{pgfonlayer}" +%token DRAW_CMD "\\draw" +%token NODE_CMD "\\node" +%token PATH_CMD "\\path" +%token RECTANGLE "rectangle" +%token NODE "node" +%token AT "at" +%token TO "to" +%token SEMICOLON ";" +%token COMMA "," + +%token LEFTPARENTHESIS "(" +%token RIGHTPARENTHESIS ")" +%token LEFTBRACKET "[" +%token RIGHTBRACKET "]" +%token FULLSTOP "." +%token EQUALS "=" +%token <pt> COORD "co-ordinate" +%token <nsstr> PROPSTRING "key/value string" +%token <nsstr> REFSTRING "string" +%token <nsstr> DELIMITEDSTRING "{-delimited string" + +%token UNKNOWN_BEGIN_CMD "unknown \\begin command" +%token UNKNOWN_END_CMD "unknown \\end command" +%token UNKNOWN_CMD "unknown latex command" +%token UNKNOWN_STR "unknown string" +%token UNCLOSED_DELIM_STR "unclosed {-delimited string" + +%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 + +%% + +tikzpicture: "\\begin{tikzpicture}" optproperties tikzcmds "\\end{tikzpicture}" + { + if ($2) { + [[assembler graph] setData:$2]; + } + }; +tikzcmds: tikzcmds tikzcmd | ; +tikzcmd: node | edge | boundingbox | ignore; + +ignore: "\\begin{pgfonlayer}" DELIMITEDSTRING | "\\end{pgfonlayer}"; + +optproperties: + "[" "]" + { $$ = nil; } + | "[" properties "]" + { $$ = $2; } + | { $$ = nil; }; +properties: extraproperties property + { + [$1 addObject:$2]; + $$ = $1; + }; +extraproperties: + extraproperties property "," + { + [$1 addObject:$2]; + $$ = $1; + } + | { $$ = [GraphElementData data]; }; +property: + val "=" val + { $$ = [GraphElementProperty property:$1 withValue:$3]; } + | val + { $$ = [GraphElementProperty atom:$1]; }; +val: PROPSTRING { $$ = $1; } | DELIMITEDSTRING { $$ = $1; }; + +nodename: "(" REFSTRING ")" { $$ = $2; }; +node: "\\node" optproperties nodename "at" COORD DELIMITEDSTRING ";" + { + Node *node = [[Node alloc] init]; + if ($2) + [node setData:$2]; + [node setName:$3]; + [node setPoint:$5]; + [node setLabel:$6]; + [assembler addNodeToMap:node]; + [[assembler graph] addNode:node]; +#if ! __has_feature(objc_arc) + [node release]; +#endif + }; + +optanchor: { $$ = nil; } | "." REFSTRING { $$ = $2; }; +noderef: "(" REFSTRING optanchor ")" + { + $$.node = [assembler nodeWithName:$2]; + $$.anchor = $3; + }; +optnoderef: + noderef { $$ = $1; } + | "(" ")" { $$.node = nil; $$.anchor = nil; } +optedgenode: + { $$ = nil; } + | "node" optproperties DELIMITEDSTRING + { + $$ = [Node node]; + if ($2) + [$$ setData:$2]; + [$$ setLabel:$3]; + } +edge: "\\draw" optproperties noderef "to" optedgenode optnoderef ";" + { + Edge *edge = [[Edge alloc] init]; + if ($2) + [edge setData:$2]; + [edge setSource:$3.node]; + [edge setSourceAnchor:$3.anchor]; + [edge setEdgeNode:$5]; + if ($6.node) { + [edge setTarget:$6.node]; + [edge setTargetAnchor:$6.anchor]; + } else { + [edge setTarget:$3.node]; + [edge setTargetAnchor:$3.anchor]; + } + [edge setAttributesFromData]; + [[assembler graph] addEdge:edge]; +#if ! __has_feature(objc_arc) + [edge release]; +#endif + }; + +ignoreprop: val | val "=" val; +ignoreprops: ignoreprop ignoreprops | ; +optignoreprops: "[" ignoreprops "]"; +boundingbox: + "\\path" optignoreprops COORD "rectangle" COORD ";" + { + [[assembler graph] setBoundingBox:NSRectAroundPoints($3, $5)]; + }; + +/* vi:ft=yacc:noet:ts=4:sts=4:sw=4 +*/ |