Graphviz 13.1.3~dev.20250829.0113
Loading...
Searching...
No Matches
grammar.c
Go to the documentation of this file.
1/* A Bison parser, made by GNU Bison 3.8.2. */
2
3/* Bison implementation for Yacc-like parsers in C
4
5 Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
6 Inc.
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <https://www.gnu.org/licenses/>. */
20
21/* As a special exception, you may create a larger work that contains
22 part or all of the Bison parser skeleton and distribute that work
23 under terms of your choice, so long as that work isn't itself a
24 parser generator using the skeleton or a modified version thereof
25 as a parser skeleton. Alternatively, if you modify or redistribute
26 the parser skeleton itself, you may (at your option) remove this
27 special exception, which will cause the skeleton and the resulting
28 Bison output files to be licensed under the GNU General Public
29 License without this special exception.
30
31 This special exception was added by the Free Software Foundation in
32 version 2.2 of Bison. */
33
34/* C LALR(1) parser skeleton written by Richard Stallman, by
35 simplifying the original so-called "semantic" parser. */
36
37/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
38 especially those whose name start with YY_ or yy_. They are
39 private implementation details that can be changed or removed. */
40
41/* All symbols defined below should begin with yy or YY, to avoid
42 infringing on user name space. This should be done even for local
43 variables, as they might otherwise be expanded by user macros.
44 There are some unavoidable exceptions within include files to
45 define necessary library symbols; they are noted "INFRINGES ON
46 USER NAME SPACE" below. */
47
48/* Identify Bison output, and Bison version. */
49#define YYBISON 30802
50
51/* Bison version string. */
52#define YYBISON_VERSION "3.8.2"
53
54/* Skeleton name. */
55#define YYSKELETON_NAME "yacc.c"
56
57/* Pure parsers. */
58#define YYPURE 2
59
60/* Push parsers. */
61#define YYPUSH 0
62
63/* Pull parsers. */
64#define YYPULL 1
65
66/* Substitute the type names. */
67#define YYSTYPE AAGSTYPE
68/* Substitute the variable and function names. */
69#define yyparse aagparse
70#define yylex aaglex
71#define yyerror aagerror
72#define yydebug aagdebug
73#define yynerrs aagnerrs
74
75/* First part of user prologue. */
76#line 61 "../../lib/cgraph/grammar.y"
77
78
79#include <stdbool.h>
80#include <stdio.h>
81#include <cghdr.h>
82#include <stdlib.h>
83#include <util/alloc.h>
84#include <util/gv_math.h>
85#include <util/streq.h>
86#include <util/unreachable.h>
87
88static const char Key[] = "key";
89
90typedef union s { /* possible items in generic list */
94 Agsym_t *asym; /* bound attribute */
95 char *name; /* unbound attribute */
96 struct item_s *list; /* list-of-lists (for edgestmt) */
98
99typedef struct item_s { /* generic list */
100 int tag; /* T_node, T_subgraph, T_edge, T_attr */
101 val_t u; /* primary element */
102 char *str; /* secondary value - port or attr value */
103 struct item_s *next;
105
106typedef struct list_s { /* maintain head and tail ptrs for fast append */
110
117
118/* functions */
119static void appendnode(aagscan_t scanner, char *name, char *port, char *sport);
120static void attrstmt(aagscan_t scanner, int tkind, char *macroname);
121static void startgraph(aagscan_t scanner, char *name, bool directed, bool strict);
122static void getedgeitems(aagscan_t scanner);
123static void newedge(aagscan_t scanner, Agnode_t *t, char *tport, Agnode_t *h, char *hport, char *key);
124static void edgerhs(aagscan_t scanner, Agnode_t *n, char *tport, item *hlist, char *key);
125static void appendattr(aagscan_t scanner, char *name, char *value);
126static void bindattrs(aagextra_t *ctx, int kind);
127static void applyattrs(aagextra_t *ctx, void *obj);
128static void endgraph(aagscan_t scanner);
129static void endnode(aagscan_t scanner);
130static void endedge(aagscan_t scanner);
131static void freestack(aagscan_t scanner);
132static char* concat(aagscan_t scanner, char*, char*);
133static char* concatPort(Agraph_t *G, char*, char*);
134
135static void opensubg(aagscan_t scanner, char *name);
136static void closesubg(aagscan_t scanner);
137static void graph_error(aagscan_t scanner);
138
139
140#line 141 "grammar.c"
141
142# ifndef YY_CAST
143# ifdef __cplusplus
144# define YY_CAST(Type, Val) static_cast<Type> (Val)
145# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type> (Val)
146# else
147# define YY_CAST(Type, Val) ((Type) (Val))
148# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val))
149# endif
150# endif
151# ifndef YY_NULLPTR
152# if defined __cplusplus
153# if 201103L <= __cplusplus
154# define YY_NULLPTR nullptr
155# else
156# define YY_NULLPTR 0
157# endif
158# else
159# define YY_NULLPTR ((void*)0)
160# endif
161# endif
162
163#include "grammar.h"
164/* Symbol kind. */
166{
168 YYSYMBOL_YYEOF = 0, /* "end of file" */
169 YYSYMBOL_YYerror = 1, /* error */
170 YYSYMBOL_YYUNDEF = 2, /* "invalid token" */
171 YYSYMBOL_T_graph = 3, /* T_graph */
172 YYSYMBOL_T_node = 4, /* T_node */
173 YYSYMBOL_T_edge = 5, /* T_edge */
174 YYSYMBOL_T_digraph = 6, /* T_digraph */
175 YYSYMBOL_T_subgraph = 7, /* T_subgraph */
176 YYSYMBOL_T_strict = 8, /* T_strict */
177 YYSYMBOL_T_edgeop = 9, /* T_edgeop */
178 YYSYMBOL_T_list = 10, /* T_list */
179 YYSYMBOL_T_attr = 11, /* T_attr */
180 YYSYMBOL_T_atom = 12, /* T_atom */
181 YYSYMBOL_T_qatom = 13, /* T_qatom */
182 YYSYMBOL_14_ = 14, /* '{' */
183 YYSYMBOL_15_ = 15, /* '}' */
184 YYSYMBOL_16_ = 16, /* ';' */
185 YYSYMBOL_17_ = 17, /* ',' */
186 YYSYMBOL_18_ = 18, /* ':' */
187 YYSYMBOL_19_ = 19, /* '=' */
188 YYSYMBOL_20_ = 20, /* '[' */
189 YYSYMBOL_21_ = 21, /* ']' */
190 YYSYMBOL_22_ = 22, /* '+' */
191 YYSYMBOL_YYACCEPT = 23, /* $accept */
192 YYSYMBOL_graph = 24, /* graph */
193 YYSYMBOL_body = 25, /* body */
194 YYSYMBOL_hdr = 26, /* hdr */
195 YYSYMBOL_optgraphname = 27, /* optgraphname */
196 YYSYMBOL_optstrict = 28, /* optstrict */
197 YYSYMBOL_graphtype = 29, /* graphtype */
198 YYSYMBOL_optstmtlist = 30, /* optstmtlist */
199 YYSYMBOL_stmtlist = 31, /* stmtlist */
200 YYSYMBOL_optsemi = 32, /* optsemi */
201 YYSYMBOL_stmt = 33, /* stmt */
202 YYSYMBOL_compound = 34, /* compound */
203 YYSYMBOL_simple = 35, /* simple */
204 YYSYMBOL_rcompound = 36, /* rcompound */
205 YYSYMBOL_37_1 = 37, /* $@1 */
206 YYSYMBOL_38_2 = 38, /* $@2 */
207 YYSYMBOL_nodelist = 39, /* nodelist */
208 YYSYMBOL_node = 40, /* node */
209 YYSYMBOL_attrstmt = 41, /* attrstmt */
210 YYSYMBOL_attrtype = 42, /* attrtype */
211 YYSYMBOL_optmacroname = 43, /* optmacroname */
212 YYSYMBOL_optattr = 44, /* optattr */
213 YYSYMBOL_attrlist = 45, /* attrlist */
214 YYSYMBOL_optattrdefs = 46, /* optattrdefs */
215 YYSYMBOL_attrdefs = 47, /* attrdefs */
216 YYSYMBOL_attrassignment = 48, /* attrassignment */
217 YYSYMBOL_graphattrdefs = 49, /* graphattrdefs */
218 YYSYMBOL_subgraph = 50, /* subgraph */
219 YYSYMBOL_51_3 = 51, /* $@3 */
220 YYSYMBOL_optsubghdr = 52, /* optsubghdr */
221 YYSYMBOL_optseparator = 53, /* optseparator */
222 YYSYMBOL_atom = 54, /* atom */
223 YYSYMBOL_qatom = 55 /* qatom */
226
227
228
229
230#ifdef short
231# undef short
232#endif
233
234/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
235 <limits.h> and (if available) <stdint.h> are included
236 so that the code can choose integer types of a good width. */
237
238#ifndef __PTRDIFF_MAX__
239# include <limits.h> /* INFRINGES ON USER NAME SPACE */
240# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
241# include <stdint.h> /* INFRINGES ON USER NAME SPACE */
242# define YY_STDINT_H
243# endif
244#endif
245
246/* Narrow types that promote to a signed type and that can represent a
247 signed or unsigned integer of at least N bits. In tables they can
248 save space and decrease cache pressure. Promoting to a signed type
249 helps avoid bugs in integer arithmetic. */
250
251#ifdef __INT_LEAST8_MAX__
252typedef __INT_LEAST8_TYPE__ yytype_int8;
253#elif defined YY_STDINT_H
254typedef int_least8_t yytype_int8;
255#else
256typedef signed char yytype_int8;
257#endif
258
259#ifdef __INT_LEAST16_MAX__
260typedef __INT_LEAST16_TYPE__ yytype_int16;
261#elif defined YY_STDINT_H
262typedef int_least16_t yytype_int16;
263#else
264typedef short yytype_int16;
265#endif
266
267/* Work around bug in HP-UX 11.23, which defines these macros
268 incorrectly for preprocessor constants. This workaround can likely
269 be removed in 2023, as HPE has promised support for HP-UX 11.23
270 (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of
271 <https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>. */
272#ifdef __hpux
273# undef UINT_LEAST8_MAX
274# undef UINT_LEAST16_MAX
275# define UINT_LEAST8_MAX 255
276# define UINT_LEAST16_MAX 65535
277#endif
278
279#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
280typedef __UINT_LEAST8_TYPE__ yytype_uint8;
281#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
282 && UINT_LEAST8_MAX <= INT_MAX)
283typedef uint_least8_t yytype_uint8;
284#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
285typedef unsigned char yytype_uint8;
286#else
287typedef short yytype_uint8;
288#endif
289
290#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
291typedef __UINT_LEAST16_TYPE__ yytype_uint16;
292#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \
293 && UINT_LEAST16_MAX <= INT_MAX)
294typedef uint_least16_t yytype_uint16;
295#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
296typedef unsigned short yytype_uint16;
297#else
298typedef int yytype_uint16;
299#endif
300
301#ifndef YYPTRDIFF_T
302# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
303# define YYPTRDIFF_T __PTRDIFF_TYPE__
304# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
305# elif defined PTRDIFF_MAX
306# ifndef ptrdiff_t
307# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
308# endif
309# define YYPTRDIFF_T ptrdiff_t
310# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
311# else
312# define YYPTRDIFF_T long
313# define YYPTRDIFF_MAXIMUM LONG_MAX
314# endif
315#endif
316
317#ifndef YYSIZE_T
318# ifdef __SIZE_TYPE__
319# define YYSIZE_T __SIZE_TYPE__
320# elif defined size_t
321# define YYSIZE_T size_t
322# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
323# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
324# define YYSIZE_T size_t
325# else
326# define YYSIZE_T unsigned
327# endif
328#endif
329
330#define YYSIZE_MAXIMUM \
331 YY_CAST (YYPTRDIFF_T, \
332 (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \
333 ? YYPTRDIFF_MAXIMUM \
334 : YY_CAST (YYSIZE_T, -1)))
335
336#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
337
338
339/* Stored state numbers (used for stacks). */
341
342/* State numbers in computations. */
343typedef int yy_state_fast_t;
344
345#ifndef YY_
346# if defined YYENABLE_NLS && YYENABLE_NLS
347# if ENABLE_NLS
348# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
349# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
350# endif
351# endif
352# ifndef YY_
353# define YY_(Msgid) Msgid
354# endif
355#endif
356
357
358#ifndef YY_ATTRIBUTE_PURE
359# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
360# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))
361# else
362# define YY_ATTRIBUTE_PURE
363# endif
364#endif
365
366#ifndef YY_ATTRIBUTE_UNUSED
367# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
368# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
369# else
370# define YY_ATTRIBUTE_UNUSED
371# endif
372#endif
373
374/* Suppress unused-variable warnings by "using" E. */
375#if ! defined lint || defined __GNUC__
376# define YY_USE(E) ((void) (E))
377#else
378# define YY_USE(E) /* empty */
379#endif
380
381/* Suppress an incorrect diagnostic about yylval being uninitialized. */
382#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
383# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
384# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
385 _Pragma ("GCC diagnostic push") \
386 _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")
387# else
388# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
389 _Pragma ("GCC diagnostic push") \
390 _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \
391 _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
392# endif
393# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
394 _Pragma ("GCC diagnostic pop")
395#else
396# define YY_INITIAL_VALUE(Value) Value
397#endif
398#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
399# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
400# define YY_IGNORE_MAYBE_UNINITIALIZED_END
401#endif
402#ifndef YY_INITIAL_VALUE
403# define YY_INITIAL_VALUE(Value) /* Nothing. */
404#endif
405
406#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__
407# define YY_IGNORE_USELESS_CAST_BEGIN \
408 _Pragma ("GCC diagnostic push") \
409 _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"")
410# define YY_IGNORE_USELESS_CAST_END \
411 _Pragma ("GCC diagnostic pop")
412#endif
413#ifndef YY_IGNORE_USELESS_CAST_BEGIN
414# define YY_IGNORE_USELESS_CAST_BEGIN
415# define YY_IGNORE_USELESS_CAST_END
416#endif
417
418
419#define YY_ASSERT(E) ((void) (0 && (E)))
420
421#if !defined yyoverflow
422
423/* The parser invokes alloca or malloc; define the necessary symbols. */
424
425# ifdef YYSTACK_USE_ALLOCA
426# if YYSTACK_USE_ALLOCA
427# ifdef __GNUC__
428# define YYSTACK_ALLOC __builtin_alloca
429# elif defined __BUILTIN_VA_ARG_INCR
430# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
431# elif defined _AIX
432# define YYSTACK_ALLOC __alloca
433# elif defined _MSC_VER
434# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
435# define alloca _alloca
436# else
437# define YYSTACK_ALLOC alloca
438# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
439# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
440 /* Use EXIT_SUCCESS as a witness for stdlib.h. */
441# ifndef EXIT_SUCCESS
442# define EXIT_SUCCESS 0
443# endif
444# endif
445# endif
446# endif
447# endif
448
449# ifdef YYSTACK_ALLOC
450 /* Pacify GCC's 'empty if-body' warning. */
451# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
452# ifndef YYSTACK_ALLOC_MAXIMUM
453 /* The OS might guarantee only one guard page at the bottom of the stack,
454 and a page size can be as small as 4096 bytes. So we cannot safely
455 invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
456 to allow for a few compiler-allocated temporary stack slots. */
457# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
458# endif
459# else
460# define YYSTACK_ALLOC YYMALLOC
461# define YYSTACK_FREE YYFREE
462# ifndef YYSTACK_ALLOC_MAXIMUM
463# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
464# endif
465# if (defined __cplusplus && ! defined EXIT_SUCCESS \
466 && ! ((defined YYMALLOC || defined malloc) \
467 && (defined YYFREE || defined free)))
468# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
469# ifndef EXIT_SUCCESS
470# define EXIT_SUCCESS 0
471# endif
472# endif
473# ifndef YYMALLOC
474# define YYMALLOC malloc
475# if ! defined malloc && ! defined EXIT_SUCCESS
476void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
477# endif
478# endif
479# ifndef YYFREE
480# define YYFREE free
481# if ! defined free && ! defined EXIT_SUCCESS
482void free (void *); /* INFRINGES ON USER NAME SPACE */
483# endif
484# endif
485# endif
486#endif /* !defined yyoverflow */
487
488#if (! defined yyoverflow \
489 && (! defined __cplusplus \
490 || (defined AAGSTYPE_IS_TRIVIAL && AAGSTYPE_IS_TRIVIAL)))
491
492/* A type that is properly aligned for any stack member. */
493union yyalloc
494{
495 yy_state_t yyss_alloc;
496 YYSTYPE yyvs_alloc;
497};
498
499/* The size of the maximum gap between one aligned stack and the next. */
500# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1)
501
502/* The size of an array large to enough to hold all stacks, each with
503 N elements. */
504# define YYSTACK_BYTES(N) \
505 ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \
506 + YYSTACK_GAP_MAXIMUM)
507
508# define YYCOPY_NEEDED 1
509
510/* Relocate STACK from its old location to the new one. The
511 local variables YYSIZE and YYSTACKSIZE give the old and new number of
512 elements in the stack, and YYPTR gives the new location of the
513 stack. Advance YYPTR to a properly aligned location for the next
514 stack. */
515# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
516 do \
517 { \
518 YYPTRDIFF_T yynewbytes; \
519 YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
520 Stack = &yyptr->Stack_alloc; \
521 yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \
522 yyptr += yynewbytes / YYSIZEOF (*yyptr); \
523 } \
524 while (0)
525
526#endif
527
528#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
529/* Copy COUNT objects from SRC to DST. The source and destination do
530 not overlap. */
531# ifndef YYCOPY
532# if defined __GNUC__ && 1 < __GNUC__
533# define YYCOPY(Dst, Src, Count) \
534 __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src)))
535# else
536# define YYCOPY(Dst, Src, Count) \
537 do \
538 { \
539 YYPTRDIFF_T yyi; \
540 for (yyi = 0; yyi < (Count); yyi++) \
541 (Dst)[yyi] = (Src)[yyi]; \
542 } \
543 while (0)
544# endif
545# endif
546#endif /* !YYCOPY_NEEDED */
547
548/* YYFINAL -- State number of the termination state. */
549#define YYFINAL 6
550/* YYLAST -- Last index in YYTABLE. */
551#define YYLAST 59
552
553/* YYNTOKENS -- Number of terminals. */
554#define YYNTOKENS 23
555/* YYNNTS -- Number of nonterminals. */
556#define YYNNTS 33
557/* YYNRULES -- Number of rules. */
558#define YYNRULES 59
559/* YYNSTATES -- Number of states. */
560#define YYNSTATES 76
561
562/* YYMAXUTOK -- Last valid token kind. */
563#define YYMAXUTOK 268
564
565
566/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
567 as returned by yylex, with out-of-bounds checking. */
568#define YYTRANSLATE(YYX) \
569 (0 <= (YYX) && (YYX) <= YYMAXUTOK \
570 ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \
571 : YYSYMBOL_YYUNDEF)
572
573/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
574 as returned by yylex. */
575static const yytype_int8 yytranslate[] =
576{
577 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
578 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
579 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
580 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
581 2, 2, 2, 22, 17, 2, 2, 2, 2, 2,
582 2, 2, 2, 2, 2, 2, 2, 2, 18, 16,
583 2, 19, 2, 2, 2, 2, 2, 2, 2, 2,
584 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
585 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
586 2, 20, 2, 21, 2, 2, 2, 2, 2, 2,
587 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
588 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
589 2, 2, 2, 14, 2, 15, 2, 2, 2, 2,
590 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
591 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
592 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
593 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
594 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
595 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
596 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
597 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
598 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
599 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
600 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
601 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
602 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
603 5, 6, 7, 8, 9, 10, 11, 12, 13
604};
605
606#if AAGDEBUG
607/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
608static const yytype_uint8 yyrline[] =
609{
610 0, 142, 142, 143, 144, 147, 149, 152, 152, 154,
611 154, 156, 156, 158, 158, 160, 160, 162, 162, 164,
612 165, 168, 172, 172, 174, 174, 174, 175, 179, 179,
613 181, 182, 183, 186, 187, 190, 191, 192, 195, 196,
614 199, 199, 201, 203, 204, 206, 209, 212, 215, 215,
615 218, 219, 220, 223, 223, 223, 225, 226, 229, 230
616};
617#endif
618
620#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State])
621
622#if AAGDEBUG || 0
623/* The user-facing name of the symbol whose (internal) number is
624 YYSYMBOL. No bounds checking. */
625static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;
626
627/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
628 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
629static const char *const yytname[] =
630{
631 "\"end of file\"", "error", "\"invalid token\"", "T_graph", "T_node",
632 "T_edge", "T_digraph", "T_subgraph", "T_strict", "T_edgeop", "T_list",
633 "T_attr", "T_atom", "T_qatom", "'{'", "'}'", "';'", "','", "':'", "'='",
634 "'['", "']'", "'+'", "$accept", "graph", "body", "hdr", "optgraphname",
635 "optstrict", "graphtype", "optstmtlist", "stmtlist", "optsemi", "stmt",
636 "compound", "simple", "rcompound", "$@1", "$@2", "nodelist", "node",
637 "attrstmt", "attrtype", "optmacroname", "optattr", "attrlist",
638 "optattrdefs", "attrdefs", "attrassignment", "graphattrdefs", "subgraph",
639 "$@3", "optsubghdr", "optseparator", "atom", "qatom", YY_NULLPTR
640};
641
642static const char *
644{
645 return yytname[yysymbol];
646}
647#endif
648
649#define YYPACT_NINF (-18)
650
651#define yypact_value_is_default(Yyn) \
652 ((Yyn) == YYPACT_NINF)
653
654#define YYTABLE_NINF (-53)
655
656#define yytable_value_is_error(Yyn) \
657 0
658
659/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
660 STATE-NUM. */
661static const yytype_int8 yypact[] =
662{
663 17, -18, -18, 19, 8, 3, -18, -2, -18, -18,
664 -18, 1, -18, -18, -18, 1, -18, -18, 9, -2,
665 -18, 18, 21, 23, -18, 18, 1, -18, -18, -18,
666 -18, 10, 13, -18, -18, -18, -18, -18, -18, -18,
667 -18, -18, 1, -18, -18, 22, 8, 1, 1, 25,
668 14, 24, -18, -18, 27, 24, 26, -18, -18, 29,
669 -18, -18, -18, -18, 1, 21, -5, -18, -18, -18,
670 -18, 16, 30, -18, -18, -18
671};
672
673/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
674 Performed when YYTABLE does not specify something else to do. Zero
675 means the default is an error. */
676static const yytype_int8 yydefact[] =
677{
678 0, 3, 9, 0, 0, 0, 1, 14, 2, 11,
679 12, 8, 35, 36, 37, 51, 56, 58, 0, 13,
680 16, 18, 27, 22, 28, 18, 39, 47, 34, 23,
681 48, 30, 57, 6, 7, 50, 5, 15, 17, 20,
682 24, 41, 0, 19, 41, 0, 0, 0, 0, 0,
683 52, 21, 40, 29, 30, 0, 33, 38, 49, 31,
684 46, 59, 25, 44, 0, 27, 0, 32, 26, 42,
685 43, 55, 0, 53, 54, 45
686};
687
688/* YYPGOTO[NTERM-NUM]. */
689static const yytype_int8 yypgoto[] =
690{
691 -18, -18, -4, -18, -18, -18, -18, -18, -18, 31,
692 32, -18, -7, -17, -18, -18, -18, 12, -18, -18,
693 -18, 6, 15, -18, -18, -14, -18, -18, -18, -18,
694 -18, -11, -18
695};
696
697/* YYDEFGOTO[NTERM-NUM]. */
698static const yytype_int8 yydefgoto[] =
699{
700 0, 3, 8, 4, 33, 5, 11, 18, 19, 39,
701 20, 21, 22, 41, 50, 65, 23, 24, 25, 26,
702 44, 51, 52, 66, 70, 27, 28, 29, 46, 30,
703 75, 31, 32
704};
705
706/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
707 positive, shift that token. If negative, reduce the rule whose
708 number is the opposite. If YYTABLE_NINF, syntax error. */
709static const yytype_int8 yytable[] =
710{
711 34, 12, 13, 14, 35, 15, 9, 16, 17, 10,
712 16, 17, -52, 16, 17, 45, 69, -4, 1, 6,
713 -10, 15, 7, -10, 36, 2, 16, 17, 47, 48,
714 40, 54, 73, 74, 38, 49, 59, 60, 61, 54,
715 42, 57, 58, 62, 63, 47, -40, 64, 68, 48,
716 55, 37, 71, 67, 53, 72, 43, 0, 0, 56
717};
718
719static const yytype_int8 yycheck[] =
720{
721 11, 3, 4, 5, 15, 7, 3, 12, 13, 6,
722 12, 13, 14, 12, 13, 26, 21, 0, 1, 0,
723 3, 7, 14, 6, 15, 8, 12, 13, 18, 19,
724 9, 42, 16, 17, 16, 22, 47, 48, 13, 50,
725 17, 19, 46, 50, 20, 18, 20, 18, 65, 19,
726 44, 19, 66, 64, 42, 66, 25, -1, -1, 44
727};
728
729/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
730 state STATE-NUM. */
731static const yytype_int8 yystos[] =
732{
733 0, 1, 8, 24, 26, 28, 0, 14, 25, 3,
734 6, 29, 3, 4, 5, 7, 12, 13, 30, 31,
735 33, 34, 35, 39, 40, 41, 42, 48, 49, 50,
736 52, 54, 55, 27, 54, 54, 15, 33, 16, 32,
737 9, 36, 17, 32, 43, 54, 51, 18, 19, 22,
738 37, 44, 45, 40, 54, 44, 45, 19, 25, 54,
739 54, 13, 35, 20, 18, 38, 46, 54, 36, 21,
740 47, 48, 54, 16, 17, 53
741};
742
743/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */
744static const yytype_int8 yyr1[] =
745{
746 0, 23, 24, 24, 24, 25, 26, 27, 27, 28,
747 28, 29, 29, 30, 30, 31, 31, 32, 32, 33,
748 33, 34, 35, 35, 37, 38, 36, 36, 39, 39,
749 40, 40, 40, 41, 41, 42, 42, 42, 43, 43,
750 44, 44, 45, 46, 46, 47, 48, 49, 51, 50,
751 52, 52, 52, 53, 53, 53, 54, 54, 55, 55
752};
753
754/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */
755static const yytype_int8 yyr2[] =
756{
757 0, 2, 2, 1, 0, 3, 3, 1, 0, 1,
758 0, 1, 1, 1, 0, 2, 1, 1, 0, 2,
759 2, 3, 1, 1, 0, 0, 5, 0, 1, 3,
760 1, 3, 5, 3, 1, 1, 1, 1, 2, 0,
761 1, 0, 4, 2, 0, 2, 3, 1, 0, 3,
762 2, 1, 0, 1, 1, 0, 1, 1, 1, 3
763};
764
765
766enum { YYENOMEM = -2 };
767
768#define yyerrok (yyerrstatus = 0)
769#define yyclearin (yychar = AAGEMPTY)
770
771#define YYACCEPT goto yyacceptlab
772#define YYABORT goto yyabortlab
773#define YYERROR goto yyerrorlab
774#define YYNOMEM goto yyexhaustedlab
775
776
777#define YYRECOVERING() (!!yyerrstatus)
778
779#define YYBACKUP(Token, Value) \
780 do \
781 if (yychar == AAGEMPTY) \
782 { \
783 yychar = (Token); \
784 yylval = (Value); \
785 YYPOPSTACK (yylen); \
786 yystate = *yyssp; \
787 goto yybackup; \
788 } \
789 else \
790 { \
791 yyerror (scanner, YY_("syntax error: cannot back up")); \
792 YYERROR; \
793 } \
794 while (0)
795
796/* Backward compatibility with an undocumented macro.
797 Use AAGerror or AAGUNDEF. */
798#define YYERRCODE AAGUNDEF
799
800
801/* Enable debugging if requested. */
802#if AAGDEBUG
803
804# ifndef YYFPRINTF
805# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
806# define YYFPRINTF fprintf
807# endif
808
809# define YYDPRINTF(Args) \
810do { \
811 if (yydebug) \
812 YYFPRINTF Args; \
813} while (0)
814
815
816
817
818# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
819do { \
820 if (yydebug) \
821 { \
822 YYFPRINTF (stderr, "%s ", Title); \
823 yy_symbol_print (stderr, \
824 Kind, Value, scanner); \
825 YYFPRINTF (stderr, "\n"); \
826 } \
827} while (0)
828
829
830/*-----------------------------------.
831| Print this symbol's value on YYO. |
832`-----------------------------------*/
833
834static void
835yy_symbol_value_print (FILE *yyo,
836 yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, aagscan_t scanner)
837{
838 FILE *yyoutput = yyo;
839 YY_USE (yyoutput);
840 YY_USE (scanner);
841 if (!yyvaluep)
842 return;
844 YY_USE (yykind);
846}
847
848
849/*---------------------------.
850| Print this symbol on YYO. |
851`---------------------------*/
852
853static void
854yy_symbol_print (FILE *yyo,
855 yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, aagscan_t scanner)
856{
857 YYFPRINTF (yyo, "%s %s (",
858 yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind));
859
860 yy_symbol_value_print (yyo, yykind, yyvaluep, scanner);
861 YYFPRINTF (yyo, ")");
862}
863
864/*------------------------------------------------------------------.
865| yy_stack_print -- Print the state stack from its BOTTOM up to its |
866| TOP (included). |
867`------------------------------------------------------------------*/
868
869static void
870yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop)
871{
872 YYFPRINTF (stderr, "Stack now");
873 for (; yybottom <= yytop; yybottom++)
874 {
875 int yybot = *yybottom;
876 YYFPRINTF (stderr, " %d", yybot);
877 }
878 YYFPRINTF (stderr, "\n");
879}
880
881# define YY_STACK_PRINT(Bottom, Top) \
882do { \
883 if (yydebug) \
884 yy_stack_print ((Bottom), (Top)); \
885} while (0)
886
887
888/*------------------------------------------------.
889| Report that the YYRULE is going to be reduced. |
890`------------------------------------------------*/
891
892static void
893yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp,
894 int yyrule, aagscan_t scanner)
895{
896 int yylno = yyrline[yyrule];
897 int yynrhs = yyr2[yyrule];
898 int yyi;
899 YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n",
900 yyrule - 1, yylno);
901 /* The symbols being reduced. */
902 for (yyi = 0; yyi < yynrhs; yyi++)
903 {
904 YYFPRINTF (stderr, " $%d = ", yyi + 1);
905 yy_symbol_print (stderr,
906 YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]),
907 &yyvsp[(yyi + 1) - (yynrhs)], scanner);
908 YYFPRINTF (stderr, "\n");
909 }
910}
911
912# define YY_REDUCE_PRINT(Rule) \
913do { \
914 if (yydebug) \
915 yy_reduce_print (yyssp, yyvsp, Rule, scanner); \
916} while (0)
917
918/* Nonzero means print parse trace. It is left uninitialized so that
919 multiple parsers can coexist. */
920int yydebug;
921#else /* !AAGDEBUG */
922# define YYDPRINTF(Args) ((void) 0)
923# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
924# define YY_STACK_PRINT(Bottom, Top)
925# define YY_REDUCE_PRINT(Rule)
926#endif /* !AAGDEBUG */
927
928
929/* YYINITDEPTH -- initial size of the parser's stacks. */
930#ifndef YYINITDEPTH
931# define YYINITDEPTH 200
932#endif
933
934/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
935 if the built-in stack extension method is used).
936
937 Do not make this value too large; the results are undefined if
938 YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
939 evaluated with infinite-precision integer arithmetic. */
940
941#ifndef YYMAXDEPTH
942# define YYMAXDEPTH 10000
943#endif
944
945
946
947
948
949
950/*-----------------------------------------------.
951| Release the memory associated to this symbol. |
952`-----------------------------------------------*/
953
954static void
955yydestruct (const char *yymsg,
956 yysymbol_kind_t yykind, YYSTYPE *yyvaluep, aagscan_t scanner)
957{
958 YY_USE (yyvaluep);
959 YY_USE (scanner);
960 if (!yymsg)
961 yymsg = "Deleting";
962 YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp);
963
965 YY_USE (yykind);
967}
968
969
970
971
972
973
974/*----------.
975| yyparse. |
976`----------*/
977
978int
980{
981/* Lookahead token kind. */
982int yychar;
983
984
985/* The semantic value of the lookahead symbol. */
986/* Default value used for initialization, for pacifying older GCCs
987 or non-GCC compilers. */
988YY_INITIAL_VALUE (static YYSTYPE yyval_default;)
989YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
990
991 /* Number of syntax errors so far. */
992 int yynerrs = 0;
993
994 yy_state_fast_t yystate = 0;
995 /* Number of tokens to shift before error messages enabled. */
996 int yyerrstatus = 0;
997
998 /* Refer to the stacks through separate pointers, to allow yyoverflow
999 to reallocate them elsewhere. */
1000
1001 /* Their size. */
1002 YYPTRDIFF_T yystacksize = YYINITDEPTH;
1003
1004 /* The state stack: array, bottom, top. */
1005 yy_state_t yyssa[YYINITDEPTH];
1006 yy_state_t *yyss = yyssa;
1007 yy_state_t *yyssp = yyss;
1008
1009 /* The semantic value stack: array, bottom, top. */
1010 YYSTYPE yyvsa[YYINITDEPTH];
1011 YYSTYPE *yyvs = yyvsa;
1012 YYSTYPE *yyvsp = yyvs;
1013
1014 int yyn;
1015 /* The return value of yyparse. */
1016 int yyresult;
1017 /* Lookahead symbol kind. */
1019 /* The variables used to return semantic value and location from the
1020 action routines. */
1021 YYSTYPE yyval;
1022
1023
1024
1025#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1026
1027 /* The number of symbols on the RHS of the reduced rule.
1028 Keep to zero when no symbol should be popped. */
1029 int yylen = 0;
1030
1031 YYDPRINTF ((stderr, "Starting parse\n"));
1032
1033 yychar = AAGEMPTY; /* Cause a token to be read. */
1034
1035 goto yysetstate;
1036
1037
1038/*------------------------------------------------------------.
1039| yynewstate -- push a new state, which is found in yystate. |
1040`------------------------------------------------------------*/
1041yynewstate:
1042 /* In all cases, when you get here, the value and location stacks
1043 have just been pushed. So pushing a state here evens the stacks. */
1044 yyssp++;
1045
1046
1047/*--------------------------------------------------------------------.
1048| yysetstate -- set current state (the top of the stack) to yystate. |
1049`--------------------------------------------------------------------*/
1050yysetstate:
1051 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1052 YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
1054 *yyssp = YY_CAST (yy_state_t, yystate);
1056 YY_STACK_PRINT (yyss, yyssp);
1057
1058 if (yyss + yystacksize - 1 <= yyssp)
1059#if !defined yyoverflow && !defined YYSTACK_RELOCATE
1060 YYNOMEM;
1061#else
1062 {
1063 /* Get the current used size of the three stacks, in elements. */
1064 YYPTRDIFF_T yysize = yyssp - yyss + 1;
1065
1066# if defined yyoverflow
1067 {
1068 /* Give user a chance to reallocate the stack. Use copies of
1069 these so that the &'s don't force the real ones into
1070 memory. */
1071 yy_state_t *yyss1 = yyss;
1072 YYSTYPE *yyvs1 = yyvs;
1073
1074 /* Each stack pointer address is followed by the size of the
1075 data in use in that stack, in bytes. This used to be a
1076 conditional around just the two extra args, but that might
1077 be undefined if yyoverflow is a macro. */
1078 yyoverflow (YY_("memory exhausted"),
1079 &yyss1, yysize * YYSIZEOF (*yyssp),
1080 &yyvs1, yysize * YYSIZEOF (*yyvsp),
1081 &yystacksize);
1082 yyss = yyss1;
1083 yyvs = yyvs1;
1084 }
1085# else /* defined YYSTACK_RELOCATE */
1086 /* Extend the stack our own way. */
1087 if (YYMAXDEPTH <= yystacksize)
1088 YYNOMEM;
1089 yystacksize *= 2;
1090 if (YYMAXDEPTH < yystacksize)
1091 yystacksize = YYMAXDEPTH;
1092
1093 {
1094 yy_state_t *yyss1 = yyss;
1095 union yyalloc *yyptr =
1096 YY_CAST (union yyalloc *,
1097 YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
1098 if (! yyptr)
1099 YYNOMEM;
1100 YYSTACK_RELOCATE (yyss_alloc, yyss);
1101 YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1102# undef YYSTACK_RELOCATE
1103 if (yyss1 != yyssa)
1104 YYSTACK_FREE (yyss1);
1105 }
1106# endif
1107
1108 yyssp = yyss + yysize - 1;
1109 yyvsp = yyvs + yysize - 1;
1110
1112 YYDPRINTF ((stderr, "Stack size increased to %ld\n",
1113 YY_CAST (long, yystacksize)));
1115
1116 if (yyss + yystacksize - 1 <= yyssp)
1117 YYABORT;
1118 }
1119#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
1120
1121
1122 if (yystate == YYFINAL)
1123 YYACCEPT;
1124
1125 goto yybackup;
1126
1127
1128/*-----------.
1129| yybackup. |
1130`-----------*/
1131yybackup:
1132 /* Do appropriate processing given the current state. Read a
1133 lookahead token if we need one and don't already have one. */
1134
1135 /* First try to decide what to do without reference to lookahead token. */
1136 yyn = yypact[yystate];
1137 if (yypact_value_is_default (yyn))
1138 goto yydefault;
1139
1140 /* Not known => get a lookahead token if don't already have one. */
1141
1142 /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */
1143 if (yychar == AAGEMPTY)
1144 {
1145 YYDPRINTF ((stderr, "Reading a token\n"));
1146 yychar = yylex (&yylval, scanner);
1147 }
1148
1149 if (yychar <= AAGEOF)
1150 {
1151 yychar = AAGEOF;
1152 yytoken = YYSYMBOL_YYEOF;
1153 YYDPRINTF ((stderr, "Now at end of input.\n"));
1154 }
1155 else if (yychar == AAGerror)
1156 {
1157 /* The scanner already issued an error message, process directly
1158 to error recovery. But do not keep the error token as
1159 lookahead, it is too special and may lead us to an endless
1160 loop in error recovery. */
1161 yychar = AAGUNDEF;
1162 yytoken = YYSYMBOL_YYerror;
1163 goto yyerrlab1;
1164 }
1165 else
1166 {
1167 yytoken = YYTRANSLATE (yychar);
1168 YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1169 }
1170
1171 /* If the proper action on seeing token YYTOKEN is to reduce or to
1172 detect an error, take that action. */
1173 yyn += yytoken;
1174 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1175 goto yydefault;
1176 yyn = yytable[yyn];
1177 if (yyn <= 0)
1178 {
1179 if (yytable_value_is_error (yyn))
1180 goto yyerrlab;
1181 yyn = -yyn;
1182 goto yyreduce;
1183 }
1184
1185 /* Count tokens shifted since error; after three, turn off error
1186 status. */
1187 if (yyerrstatus)
1188 yyerrstatus--;
1189
1190 /* Shift the lookahead token. */
1191 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1192 yystate = yyn;
1194 *++yyvsp = yylval;
1196
1197 /* Discard the shifted token. */
1198 yychar = AAGEMPTY;
1199 goto yynewstate;
1200
1201
1202/*-----------------------------------------------------------.
1203| yydefault -- do the default action for the current state. |
1204`-----------------------------------------------------------*/
1205yydefault:
1206 yyn = yydefact[yystate];
1207 if (yyn == 0)
1208 goto yyerrlab;
1209 goto yyreduce;
1210
1211
1212/*-----------------------------.
1213| yyreduce -- do a reduction. |
1214`-----------------------------*/
1215yyreduce:
1216 /* yyn is the number of a rule to reduce with. */
1217 yylen = yyr2[yyn];
1218
1219 /* If YYLEN is nonzero, implement the default value of the action:
1220 '$$ = $1'.
1221
1222 Otherwise, the following line sets YYVAL to garbage.
1223 This behavior is undocumented and Bison
1224 users should not rely upon it. Assigning to YYVAL
1225 unconditionally makes the parser a bit smaller, and it avoids a
1226 GCC warning that YYVAL may be used uninitialized. */
1227 yyval = yyvsp[1-yylen];
1228
1229
1230 YY_REDUCE_PRINT (yyn);
1231 switch (yyn)
1232 {
1233 case 2: /* graph: hdr body */
1234#line 142 "../../lib/cgraph/grammar.y"
1236#line 1237 "grammar.c"
1237 break;
1238
1239 case 3: /* graph: error */
1240#line 143 "../../lib/cgraph/grammar.y"
1242#line 1243 "grammar.c"
1243 break;
1244
1245 case 6: /* hdr: optstrict graphtype optgraphname */
1246#line 149 "../../lib/cgraph/grammar.y"
1247 {startgraph(scanner,(yyvsp[0].str),(yyvsp[-1].i) != 0,(yyvsp[-2].i) != 0);}
1248#line 1249 "grammar.c"
1249 break;
1250
1251 case 7: /* optgraphname: atom */
1252#line 152 "../../lib/cgraph/grammar.y"
1253 {(yyval.str)=(yyvsp[0].str);}
1254#line 1255 "grammar.c"
1255 break;
1256
1257 case 8: /* optgraphname: %empty */
1258#line 152 "../../lib/cgraph/grammar.y"
1259 {(yyval.str)=0;}
1260#line 1261 "grammar.c"
1261 break;
1262
1263 case 9: /* optstrict: T_strict */
1264#line 154 "../../lib/cgraph/grammar.y"
1265 {(yyval.i)=1;}
1266#line 1267 "grammar.c"
1267 break;
1268
1269 case 10: /* optstrict: %empty */
1270#line 154 "../../lib/cgraph/grammar.y"
1271 {(yyval.i)=0;}
1272#line 1273 "grammar.c"
1273 break;
1274
1275 case 11: /* graphtype: T_graph */
1276#line 156 "../../lib/cgraph/grammar.y"
1277 {(yyval.i) = 0;}
1278#line 1279 "grammar.c"
1279 break;
1280
1281 case 12: /* graphtype: T_digraph */
1282#line 156 "../../lib/cgraph/grammar.y"
1283 {(yyval.i) = 1;}
1284#line 1285 "grammar.c"
1285 break;
1286
1287 case 21: /* compound: simple rcompound optattr */
1288#line 169 "../../lib/cgraph/grammar.y"
1289 {if ((yyvsp[-1].i)) endedge(scanner); else endnode(scanner);}
1290#line 1291 "grammar.c"
1291 break;
1292
1293 case 24: /* $@1: %empty */
1294#line 174 "../../lib/cgraph/grammar.y"
1296#line 1297 "grammar.c"
1297 break;
1298
1299 case 25: /* $@2: %empty */
1300#line 174 "../../lib/cgraph/grammar.y"
1302#line 1303 "grammar.c"
1303 break;
1304
1305 case 26: /* rcompound: T_edgeop $@1 simple $@2 rcompound */
1306#line 174 "../../lib/cgraph/grammar.y"
1307 {(yyval.i) = 1;}
1308#line 1309 "grammar.c"
1309 break;
1310
1311 case 27: /* rcompound: %empty */
1312#line 175 "../../lib/cgraph/grammar.y"
1313 {(yyval.i) = 0;}
1314#line 1315 "grammar.c"
1315 break;
1316
1317 case 30: /* node: atom */
1318#line 181 "../../lib/cgraph/grammar.y"
1319 {appendnode(scanner,(yyvsp[0].str),NULL,NULL);}
1320#line 1321 "grammar.c"
1321 break;
1322
1323 case 31: /* node: atom ':' atom */
1324#line 182 "../../lib/cgraph/grammar.y"
1325 {appendnode(scanner,(yyvsp[-2].str),(yyvsp[0].str),NULL);}
1326#line 1327 "grammar.c"
1327 break;
1328
1329 case 32: /* node: atom ':' atom ':' atom */
1330#line 183 "../../lib/cgraph/grammar.y"
1331 {appendnode(scanner,(yyvsp[-4].str),(yyvsp[-2].str),(yyvsp[0].str));}
1332#line 1333 "grammar.c"
1333 break;
1334
1335 case 33: /* attrstmt: attrtype optmacroname attrlist */
1336#line 186 "../../lib/cgraph/grammar.y"
1337 {attrstmt(scanner,(yyvsp[-2].i),(yyvsp[-1].str));}
1338#line 1339 "grammar.c"
1339 break;
1340
1341 case 34: /* attrstmt: graphattrdefs */
1342#line 187 "../../lib/cgraph/grammar.y"
1344#line 1345 "grammar.c"
1345 break;
1346
1347 case 35: /* attrtype: T_graph */
1348#line 190 "../../lib/cgraph/grammar.y"
1349 {(yyval.i) = T_graph;}
1350#line 1351 "grammar.c"
1351 break;
1352
1353 case 36: /* attrtype: T_node */
1354#line 191 "../../lib/cgraph/grammar.y"
1355 {(yyval.i) = T_node;}
1356#line 1357 "grammar.c"
1357 break;
1358
1359 case 37: /* attrtype: T_edge */
1360#line 192 "../../lib/cgraph/grammar.y"
1361 {(yyval.i) = T_edge;}
1362#line 1363 "grammar.c"
1363 break;
1364
1365 case 38: /* optmacroname: atom '=' */
1366#line 195 "../../lib/cgraph/grammar.y"
1367 {(yyval.str) = (yyvsp[-1].str);}
1368#line 1369 "grammar.c"
1369 break;
1370
1371 case 39: /* optmacroname: %empty */
1372#line 196 "../../lib/cgraph/grammar.y"
1373 {(yyval.str) = NULL; }
1374#line 1375 "grammar.c"
1375 break;
1376
1377 case 46: /* attrassignment: atom '=' atom */
1378#line 209 "../../lib/cgraph/grammar.y"
1379 {appendattr(scanner,(yyvsp[-2].str),(yyvsp[0].str));}
1380#line 1381 "grammar.c"
1381 break;
1382
1383 case 48: /* $@3: %empty */
1384#line 215 "../../lib/cgraph/grammar.y"
1385 {opensubg(scanner,(yyvsp[0].str));}
1386#line 1387 "grammar.c"
1387 break;
1388
1389 case 49: /* subgraph: optsubghdr $@3 body */
1390#line 215 "../../lib/cgraph/grammar.y"
1391 {closesubg(scanner);}
1392#line 1393 "grammar.c"
1393 break;
1394
1395 case 50: /* optsubghdr: T_subgraph atom */
1396#line 218 "../../lib/cgraph/grammar.y"
1397 {(yyval.str)=(yyvsp[0].str);}
1398#line 1399 "grammar.c"
1399 break;
1400
1401 case 51: /* optsubghdr: T_subgraph */
1402#line 219 "../../lib/cgraph/grammar.y"
1403 {(yyval.str)=NULL;}
1404#line 1405 "grammar.c"
1405 break;
1406
1407 case 52: /* optsubghdr: %empty */
1408#line 220 "../../lib/cgraph/grammar.y"
1409 {(yyval.str)=NULL;}
1410#line 1411 "grammar.c"
1411 break;
1412
1413 case 56: /* atom: T_atom */
1414#line 225 "../../lib/cgraph/grammar.y"
1415 {(yyval.str) = (yyvsp[0].str);}
1416#line 1417 "grammar.c"
1417 break;
1418
1419 case 57: /* atom: qatom */
1420#line 226 "../../lib/cgraph/grammar.y"
1421 {(yyval.str) = (yyvsp[0].str);}
1422#line 1423 "grammar.c"
1423 break;
1424
1425 case 58: /* qatom: T_qatom */
1426#line 229 "../../lib/cgraph/grammar.y"
1427 {(yyval.str) = (yyvsp[0].str);}
1428#line 1429 "grammar.c"
1429 break;
1430
1431 case 59: /* qatom: qatom '+' T_qatom */
1432#line 230 "../../lib/cgraph/grammar.y"
1433 {(yyval.str) = concat(scanner, (yyvsp[-2].str),(yyvsp[0].str));}
1434#line 1435 "grammar.c"
1435 break;
1436
1437
1438#line 1439 "grammar.c"
1439
1440 default: break;
1441 }
1442 /* User semantic actions sometimes alter yychar, and that requires
1443 that yytoken be updated with the new translation. We take the
1444 approach of translating immediately before every use of yytoken.
1445 One alternative is translating here after every semantic action,
1446 but that translation would be missed if the semantic action invokes
1447 YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
1448 if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
1449 incorrect destructor might then be invoked immediately. In the
1450 case of YYERROR or YYBACKUP, subsequent parser actions might lead
1451 to an incorrect destructor call or verbose syntax error message
1452 before the lookahead is translated. */
1453 YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc);
1454
1455 YYPOPSTACK (yylen);
1456 yylen = 0;
1457
1458 *++yyvsp = yyval;
1459
1460 /* Now 'shift' the result of the reduction. Determine what state
1461 that goes to, based on the state we popped back to and the rule
1462 number reduced by. */
1463 {
1464 const int yylhs = yyr1[yyn] - YYNTOKENS;
1465 const int yyi = yypgoto[yylhs] + *yyssp;
1466 yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
1467 ? yytable[yyi]
1468 : yydefgoto[yylhs]);
1469 }
1470
1471 goto yynewstate;
1472
1473
1474/*--------------------------------------.
1475| yyerrlab -- here on detecting error. |
1476`--------------------------------------*/
1477yyerrlab:
1478 /* Make sure we have latest lookahead translation. See comments at
1479 user semantic actions for why this is necessary. */
1481 /* If not already recovering from an error, report this error. */
1482 if (!yyerrstatus)
1483 {
1484 ++yynerrs;
1485 yyerror (scanner, YY_("syntax error"));
1486 }
1487
1488 if (yyerrstatus == 3)
1489 {
1490 /* If just tried and failed to reuse lookahead token after an
1491 error, discard it. */
1492
1493 if (yychar <= AAGEOF)
1494 {
1495 /* Return failure if at end of input. */
1496 if (yychar == AAGEOF)
1497 YYABORT;
1498 }
1499 else
1500 {
1501 yydestruct ("Error: discarding",
1502 yytoken, &yylval, scanner);
1503 yychar = AAGEMPTY;
1504 }
1505 }
1506
1507 /* Else will try to reuse lookahead token after shifting the error
1508 token. */
1509 goto yyerrlab1;
1510
1511
1512/*---------------------------------------------------.
1513| yyerrorlab -- error raised explicitly by YYERROR. |
1514`---------------------------------------------------*/
1515yyerrorlab:
1516 /* Pacify compilers when the user code never invokes YYERROR and the
1517 label yyerrorlab therefore never appears in user code. */
1518 if (0)
1519 YYERROR;
1520 ++yynerrs;
1521
1522 /* Do not reclaim the symbols of the rule whose action triggered
1523 this YYERROR. */
1524 YYPOPSTACK (yylen);
1525 yylen = 0;
1526 YY_STACK_PRINT (yyss, yyssp);
1527 yystate = *yyssp;
1528 goto yyerrlab1;
1529
1530
1531/*-------------------------------------------------------------.
1532| yyerrlab1 -- common code for both syntax error and YYERROR. |
1533`-------------------------------------------------------------*/
1534yyerrlab1:
1535 yyerrstatus = 3; /* Each real token shifted decrements this. */
1536
1537 /* Pop stack until we find a state that shifts the error token. */
1538 for (;;)
1539 {
1540 yyn = yypact[yystate];
1541 if (!yypact_value_is_default (yyn))
1542 {
1543 yyn += YYSYMBOL_YYerror;
1544 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror)
1545 {
1546 yyn = yytable[yyn];
1547 if (0 < yyn)
1548 break;
1549 }
1550 }
1551
1552 /* Pop the current state because it cannot handle the error token. */
1553 if (yyssp == yyss)
1554 YYABORT;
1555
1556
1557 yydestruct ("Error: popping",
1558 YY_ACCESSING_SYMBOL (yystate), yyvsp, scanner);
1559 YYPOPSTACK (1);
1560 yystate = *yyssp;
1561 YY_STACK_PRINT (yyss, yyssp);
1562 }
1563
1565 *++yyvsp = yylval;
1567
1568
1569 /* Shift the error token. */
1570 YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp);
1571
1572 yystate = yyn;
1573 goto yynewstate;
1574
1575
1576/*-------------------------------------.
1577| yyacceptlab -- YYACCEPT comes here. |
1578`-------------------------------------*/
1579yyacceptlab:
1580 yyresult = 0;
1581 goto yyreturnlab;
1582
1583
1584/*-----------------------------------.
1585| yyabortlab -- YYABORT comes here. |
1586`-----------------------------------*/
1587yyabortlab:
1588 yyresult = 1;
1589 goto yyreturnlab;
1590
1591
1592/*-----------------------------------------------------------.
1593| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. |
1594`-----------------------------------------------------------*/
1595yyexhaustedlab:
1596 yyerror (scanner, YY_("memory exhausted"));
1597 yyresult = 2;
1598 goto yyreturnlab;
1599
1600
1601/*----------------------------------------------------------.
1602| yyreturnlab -- parsing is finished, clean up and return. |
1603`----------------------------------------------------------*/
1604yyreturnlab:
1605 if (yychar != AAGEMPTY)
1606 {
1607 /* Make sure we have latest lookahead translation. See comments at
1608 user semantic actions for why this is necessary. */
1609 yytoken = YYTRANSLATE (yychar);
1610 yydestruct ("Cleanup: discarding lookahead",
1611 yytoken, &yylval, scanner);
1612 }
1613 /* Do not reclaim the symbols of the rule whose action triggered
1614 this YYABORT or YYACCEPT. */
1615 YYPOPSTACK (yylen);
1616 YY_STACK_PRINT (yyss, yyssp);
1617 while (yyssp != yyss)
1618 {
1619 yydestruct ("Cleanup: popping",
1620 YY_ACCESSING_SYMBOL (+*yyssp), yyvsp, scanner);
1621 YYPOPSTACK (1);
1622 }
1623#ifndef yyoverflow
1624 if (yyss != yyssa)
1625 YYSTACK_FREE (yyss);
1626#endif
1627
1628 return yyresult;
1629}
1630
1631#line 232 "../../lib/cgraph/grammar.y"
1632
1633
1634static item *newitem(int tag, void *p0, char *p1)
1635{
1636 item *rv = gv_alloc(sizeof(item));
1637 rv->tag = tag;
1638 rv->u.name = p0;
1639 rv->str = p1;
1640 return rv;
1641}
1642
1643static item *cons_node(Agnode_t *n, char *port)
1644 { return newitem(T_node,n,port); }
1645
1646static item *cons_attr(char *name, char *value)
1647 { return newitem(T_atom,name,value); }
1648
1649static item *cons_list(item *list)
1650 { return newitem(T_list,list,NULL); }
1651
1653 { return newitem(T_subgraph,subg,NULL); }
1654
1655static gstack_t *push(gstack_t *s, Agraph_t *subg) {
1656 gstack_t *rv = gv_alloc(sizeof(gstack_t));
1657 rv->down = s;
1658 rv->g = subg;
1659 return rv;
1660}
1661
1663{
1664 gstack_t *rv;
1665 rv = s->down;
1666 free(s);
1667 return rv;
1668}
1669
1670static void delete_items(Agraph_t *G, item *ilist)
1671{
1672 item *p,*pn;
1673
1674 for (p = ilist; p; p = pn) {
1675 pn = p->next;
1676 if (p->tag == T_list) delete_items(G, p->u.list);
1677 if (p->tag == T_atom) agstrfree(G, p->str, aghtmlstr(p->str));
1678 free(p);
1679 }
1680}
1681
1682static void deletelist(Agraph_t *G, list_t *list)
1683{
1684 delete_items(G,list->first);
1685 list->first = list->last = NULL;
1686}
1687
1688static void listapp(list_t *list, item *v)
1689{
1690 if (list->last) list->last->next = v;
1691 list->last = v;
1692 if (list->first == NULL) list->first = v;
1693}
1694
1695
1696/* attrs */
1697static void appendattr(aagscan_t scanner, char *name, char *value)
1698{
1699 item *v;
1701
1702 assert(value != NULL);
1703 v = cons_attr(name,value);
1704 listapp(&ctx->S->attrlist, v);
1705}
1706
1707static void bindattrs(aagextra_t *ctx, int kind)
1708{
1709 item *aptr;
1710 char *name;
1711
1712 for (aptr = ctx->S->attrlist.first; aptr; aptr = aptr->next) {
1713 assert(aptr->tag == T_atom); /* signifies unbound attr */
1714 name = aptr->u.name;
1715 if (kind == AGEDGE && streq(name,Key)) continue;
1716 if ((aptr->u.asym = agattr_text(ctx->S->g,kind,name,NULL)) == NULL)
1717 aptr->u.asym = agattr_text(ctx->S->g,kind,name,"");
1718 aptr->tag = T_attr; /* signifies bound attr */
1719 agstrfree(ctx->G, name, false);
1720 }
1721}
1722
1723/* attach node/edge specific attributes */
1724static void applyattrs(aagextra_t *ctx, void *obj)
1725{
1726 item *aptr;
1727
1728 for (aptr = ctx->S->attrlist.first; aptr; aptr = aptr->next) {
1729 if (aptr->tag == T_attr) {
1730 if (aptr->u.asym) {
1731 if (aghtmlstr(aptr->str)) {
1732 agxset_html(obj, aptr->u.asym, aptr->str);
1733 } else {
1734 agxset(obj, aptr->u.asym, aptr->str);
1735 }
1736 }
1737 }
1738 else {
1739 assert(AGTYPE(obj) == AGINEDGE || AGTYPE(obj) == AGOUTEDGE);
1740 assert(aptr->tag == T_atom);
1741 assert(streq(aptr->u.name,Key));
1742 }
1743 }
1744}
1745
1746static void nomacros(void)
1747{
1748 agwarningf("attribute macros not implemented");
1749}
1750
1751/* attrstmt:
1752 * First argument is always attrtype, so switch covers all cases.
1753 * This function is used to handle default attribute value assignment.
1754 */
1755static void attrstmt(aagscan_t scanner, int tkind, char *macroname)
1756{
1757 item *aptr;
1758 int kind = 0;
1760 Agsym_t* sym;
1761 Agraph_t *G = ctx->G;
1762 gstack_t *S = ctx->S;
1763
1764 /* creating a macro def */
1765 if (macroname) nomacros();
1766 /* invoking a macro def */
1767 for (aptr = S->attrlist.first; aptr; aptr = aptr->next)
1768 if (aptr->str == NULL) nomacros();
1769
1770 switch(tkind) {
1771 case T_graph: kind = AGRAPH; break;
1772 case T_node: kind = AGNODE; break;
1773 case T_edge: kind = AGEDGE; break;
1774 default: UNREACHABLE();
1775 }
1776 bindattrs(ctx, kind); /* set up defaults for new attributes */
1777 for (aptr = S->attrlist.first; aptr; aptr = aptr->next) {
1778 /* If the tag is still T_atom, aptr->u.asym has not been set */
1779 if (aptr->tag == T_atom) continue;
1780 if (!aptr->u.asym->fixed || S->g != G) {
1781 if (aghtmlstr(aptr->str)) {
1782 sym = agattr_html(S->g, kind, aptr->u.asym->name, aptr->str);
1783 } else {
1784 sym = agattr_text(S->g, kind, aptr->u.asym->name, aptr->str);
1785 }
1786 } else
1787 sym = aptr->u.asym;
1788 if (S->g == G)
1789 sym->print = true;
1790 }
1791 deletelist(G, &S->attrlist);
1792}
1793
1794/* nodes */
1795
1796static void appendnode(aagscan_t scanner, char *name, char *port, char *sport)
1797{
1798 item *elt;
1800 Agraph_t *G = ctx->G;
1801 gstack_t *S = ctx->S;
1802
1803 if (sport) {
1804 port = concatPort (G, port, sport);
1805 }
1806 elt = cons_node(agnode(S->g, name, 1), port);
1807 listapp(&S->nodelist, elt);
1808 agstrfree(G, name, false);
1809}
1810
1811/* apply current optional attrs to nodelist and clean up lists */
1812/* what's bad is that this could also be endsubg. also, you can't
1813clean up S->subg in closesubg() because S->subg might be needed
1814to construct edges. these are the sort of notes you write to yourself
1815in the future. */
1817{
1818 item *ptr;
1820 Agraph_t *G = ctx->G;
1821 gstack_t *S = ctx->S;
1822
1823 bindattrs(ctx, AGNODE);
1824 for (ptr = S->nodelist.first; ptr; ptr = ptr->next)
1825 applyattrs(ctx, ptr->u.n);
1826 deletelist(G, &S->nodelist);
1827 deletelist(G, &S->attrlist);
1828 deletelist(G, &S->edgelist);
1829 S->subg = 0; /* notice a pattern here? :-( */
1830}
1831
1832/* edges - store up node/subg lists until optional edge key can be seen */
1833
1835{
1837 gstack_t *S = ctx->S;
1838 item *v = 0;
1839
1840 if (S->nodelist.first) {
1841 v = cons_list(S->nodelist.first);
1842 S->nodelist.first = S->nodelist.last = NULL;
1843 }
1844 else {if (S->subg) v = cons_subg(S->subg); S->subg = 0;}
1845 /* else nil append */
1846 if (v) listapp(&S->edgelist, v);
1847}
1848
1850{
1851 char *key;
1852 item *aptr,*tptr,*p;
1853
1854 Agnode_t *t;
1855 Agraph_t *subg;
1857 Agraph_t *G = ctx->G;
1858
1859 bindattrs(ctx, AGEDGE);
1860
1861 /* look for "key" pseudo-attribute */
1862 key = NULL;
1863 for (aptr = ctx->S->attrlist.first; aptr; aptr = aptr->next) {
1864 if (aptr->tag == T_atom && streq(aptr->u.name,Key))
1865 key = aptr->str;
1866 }
1867
1868 /* can make edges with node lists or subgraphs */
1869 for (p = ctx->S->edgelist.first; p->next; p = p->next) {
1870 if (p->tag == T_subgraph) {
1871 subg = p->u.subg;
1872 for (t = agfstnode(subg); t; t = agnxtnode(subg,t))
1873 edgerhs(scanner,agsubnode(ctx->S->g, t, 0), NULL, p->next, key);
1874 }
1875 else {
1876 for (tptr = p->u.list; tptr; tptr = tptr->next)
1877 edgerhs(scanner,tptr->u.n,tptr->str,p->next,key);
1878 }
1879 }
1880 deletelist(G, &ctx->S->nodelist);
1881 deletelist(G, &ctx->S->edgelist);
1882 deletelist(G, &ctx->S->attrlist);
1883 ctx->S->subg = 0;
1884}
1885
1886/* concat:
1887 */
1888static char*
1889concat (aagscan_t scanner, char* s1, char* s2)
1890{
1891 char* s;
1892 char buf[BUFSIZ];
1893 char* sym;
1895 size_t len = strlen(s1) + strlen(s2) + 1;
1896
1897 if (len <= BUFSIZ) sym = buf;
1898 else sym = gv_alloc(len);
1899 strcpy(sym,s1);
1900 strcat(sym,s2);
1901 s = agstrdup (G,sym);
1902 agstrfree(G, s1, false);
1903 agstrfree(G, s2, false);
1904 if (sym != buf) free (sym);
1905 return s;
1906}
1907
1908static char*
1909concatPort (Agraph_t *G, char* s1, char* s2)
1910{
1911 agxbuf buf = {0};
1912
1913 agxbprint(&buf, "%s:%s", s1, s2);
1914 char *s = agstrdup(G, agxbuse(&buf));
1915 agstrfree(G, s1, false);
1916 agstrfree(G, s2, false);
1917 agxbfree(&buf);
1918 return s;
1919}
1920
1921
1922static void edgerhs(aagscan_t scanner, Agnode_t *tail, char *tport, item *hlist, char *key)
1923{
1924 Agnode_t *head;
1925 Agraph_t *subg;
1926 item *hptr;
1928
1929 if (hlist->tag == T_subgraph) {
1930 subg = hlist->u.subg;
1931 for (head = agfstnode(subg); head; head = agnxtnode(subg,head))
1932 newedge(scanner, tail, tport, agsubnode(ctx->S->g, head, 0), NULL, key);
1933 }
1934 else {
1935 for (hptr = hlist->u.list; hptr; hptr = hptr->next)
1936 newedge(scanner, tail, tport, agsubnode(ctx->S->g, hptr->u.n, 0), hptr->str, key);
1937 }
1938}
1939
1940static void mkport(aagscan_t scanner, Agedge_t *e, char *name, char *val)
1941{
1942 Agsym_t *attr;
1944
1945 if (val) {
1946 if ((attr = agattr_text(ctx->S->g,AGEDGE,name,NULL)) == NULL)
1947 attr = agattr_text(ctx->S->g,AGEDGE,name,"");
1948 agxset(e,attr,val);
1949 }
1950}
1951
1952static void newedge(aagscan_t scanner, Agnode_t *t, char *tport, Agnode_t *h, char *hport, char *key)
1953{
1954 Agedge_t *e;
1956
1957 e = agedge(ctx->S->g, t, h, key, 1);
1958 if (e) { /* can fail if graph is strict and t==h */
1959 char *tp = tport;
1960 char *hp = hport;
1961 if (agtail(e) != aghead(e) && aghead(e) == t) {
1962 /* could happen with an undirected edge */
1963 SWAP(&tp, &hp);
1964 }
1965 mkport(scanner, e,TAILPORT_ID,tp);
1966 mkport(scanner, e,HEADPORT_ID,hp);
1967 applyattrs(ctx, e);
1968 }
1969}
1970
1971/* graphs and subgraphs */
1972
1973
1974static void startgraph(aagscan_t scanner, char *name, bool directed, bool strict)
1975{
1977 if (ctx->G == NULL) {
1978 ctx->SubgraphDepth = 0;
1979 Agdesc_t req = {.directed = directed, .strict = strict, .maingraph = true};
1980 ctx->G = agopen(name,req,ctx->Disc);
1981 }
1982 ctx->S = push(ctx->S,ctx->G);
1983 agstrfree(NULL, name, false);
1984}
1985
1991
1992static void opensubg(aagscan_t scanner, char *name)
1993{
1995
1996 if (++ctx->SubgraphDepth >= YYMAXDEPTH/2) {
1997 agerrorf("subgraphs nested more than %d deep", YYMAXDEPTH);
1998 }
1999 ctx->S = push(ctx->S, agsubg(ctx->S->g, name, 1));
2000 agstrfree(ctx->G, name, false);
2001}
2002
2004{
2006 Agraph_t *subg = ctx->S->g;
2007
2008 --ctx->SubgraphDepth;
2009 ctx->S = pop(ctx->S);
2010 ctx->S->subg = subg;
2011 assert(subg);
2012}
2013
2015{
2017 while (ctx->S) {
2018 deletelist(ctx->G, &ctx->S->nodelist);
2019 deletelist(ctx->G, &ctx->S->attrlist);
2020 deletelist(ctx->G, &ctx->S->edgelist);
2021 ctx->S = pop(ctx->S);
2022 }
2023}
2024
2026{
2028 if (ctx->G) {
2031 agclose(ctx->G);
2032 ctx->G = NULL;
2033 }
2034}
2035
2036Agraph_t *agconcat(Agraph_t *g, const char *filename, void *chan,
2037 Agdisc_t *disc) {
2039 aagextra_t extra = {
2040 .Disc = disc ? disc : &AgDefaultDisc,
2041 .Ifile = chan,
2042 .G = g,
2043 .line_num = 1,
2044 .InputFile = filename,
2045 };
2046 if (aaglex_init_extra(&extra, &scanner)) {
2047 return NULL;
2048 }
2049 aagset_in(chan, scanner);
2051 if (extra.G == NULL) aglexbad(scanner);
2053 agxbfree(&extra.InputFileBuffer);
2054 agxbfree(&extra.Sbuf);
2055 return extra.G;
2056}
2057
2059 return agconcat(NULL, NULL, fp, disc);
2060}
2061
static void agxbfree(agxbuf *xb)
free any malloced resources
Definition agxbuf.h:77
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
Definition agxbuf.h:233
static WUR char * agxbuse(agxbuf *xb)
Definition agxbuf.h:306
Memory allocation wrappers that exit on failure.
static void * gv_alloc(size_t size)
Definition alloc.h:47
cgraph.h additions
int aagparse(aagscan_t scanner)
int aaglex_destroy(aagscan_t)
void aagset_in(FILE *, aagscan_t)
void aglexeof(aagscan_t yyscanner)
Definition scan.l:191
int aaglex_init_extra(aagextra_t *user_defined, aagscan_t *scanner)
void aglexbad(aagscan_t yyscanner)
Definition scan.l:196
aagextra_t * aagget_extra(aagscan_t yyscanner)
void * aagscan_t
Definition cghdr.h:106
static Agnode_t * pop(void)
Definition ccomps.c:220
#define head
Definition dthdr.h:15
static const char * yysymbol_name(yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED
Definition exparse.c:733
static const char *const yytname[]
Definition exparse.c:708
static Dtdisc_t disc
Definition exparse.y:209
#define S
Definition expr.h:72
#define G
Definition gdefs.h:7
static double len(glCompPoint p)
Definition glutils.c:136
yysymbol_kind_t
Definition gmlparse.c:287
#define YYSTYPE
Definition gmlparse.c:67
#define yychar
Definition gmlparse.c:75
#define yylval
Definition gmlparse.c:74
unsigned char yytype_uint8
Definition gmlparse.c:407
int yy_state_fast_t
Definition gmlparse.c:465
signed char yytype_int8
Definition gmlparse.c:378
yytype_int8 yy_state_t
Definition gmlparse.c:462
static const char Key[]
Definition grammar.c:88
static void attrstmt(aagscan_t scanner, int tkind, char *macroname)
Definition grammar.c:1755
#define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
Definition grammar.c:399
#define YYMAXDEPTH
Definition grammar.c:942
static void yydestruct(const char *yymsg, yysymbol_kind_t yykind, YYSTYPE *yyvaluep, aagscan_t scanner)
Definition grammar.c:955
static void opensubg(aagscan_t scanner, char *name)
Definition grammar.c:1992
#define YYSTACK_FREE
Definition grammar.c:461
static gstack_t * push(gstack_t *s, Agraph_t *subg)
Definition grammar.c:1655
static const yytype_int8 yytranslate[]
Definition grammar.c:575
static void bindattrs(aagextra_t *ctx, int kind)
Definition grammar.c:1707
yysymbol_kind_t
Definition grammar.c:166
@ YYSYMBOL_T_attr
Definition grammar.c:179
@ YYSYMBOL_rcompound
Definition grammar.c:204
@ YYSYMBOL_optmacroname
Definition grammar.c:211
@ YYSYMBOL_nodelist
Definition grammar.c:207
@ YYSYMBOL_stmt
Definition grammar.c:201
@ YYSYMBOL_YYUNDEF
Definition grammar.c:170
@ YYSYMBOL_14_
Definition grammar.c:182
@ YYSYMBOL_attrtype
Definition grammar.c:210
@ YYSYMBOL_T_atom
Definition grammar.c:180
@ YYSYMBOL_19_
Definition grammar.c:187
@ YYSYMBOL_T_subgraph
Definition grammar.c:175
@ YYSYMBOL_optgraphname
Definition grammar.c:195
@ YYSYMBOL_attrstmt
Definition grammar.c:209
@ YYSYMBOL_optsemi
Definition grammar.c:200
@ YYSYMBOL_17_
Definition grammar.c:185
@ YYSYMBOL_optattrdefs
Definition grammar.c:214
@ YYSYMBOL_51_3
Definition grammar.c:219
@ YYSYMBOL_T_qatom
Definition grammar.c:181
@ YYSYMBOL_YYerror
Definition grammar.c:169
@ YYSYMBOL_body
Definition grammar.c:193
@ YYSYMBOL_stmtlist
Definition grammar.c:199
@ YYSYMBOL_T_graph
Definition grammar.c:171
@ YYSYMBOL_graph
Definition grammar.c:192
@ YYSYMBOL_T_edge
Definition grammar.c:173
@ YYSYMBOL_qatom
Definition grammar.c:223
@ YYSYMBOL_hdr
Definition grammar.c:194
@ YYSYMBOL_attrassignment
Definition grammar.c:216
@ YYSYMBOL_37_1
Definition grammar.c:205
@ YYSYMBOL_optseparator
Definition grammar.c:221
@ YYSYMBOL_21_
Definition grammar.c:189
@ YYSYMBOL_attrlist
Definition grammar.c:213
@ YYSYMBOL_optattr
Definition grammar.c:212
@ YYSYMBOL_15_
Definition grammar.c:183
@ YYSYMBOL_20_
Definition grammar.c:188
@ YYSYMBOL_atom
Definition grammar.c:222
@ YYSYMBOL_compound
Definition grammar.c:202
@ YYSYMBOL_T_edgeop
Definition grammar.c:177
@ YYSYMBOL_18_
Definition grammar.c:186
@ YYSYMBOL_optstmtlist
Definition grammar.c:198
@ YYSYMBOL_YYACCEPT
Definition grammar.c:191
@ YYSYMBOL_T_node
Definition grammar.c:172
@ YYSYMBOL_YYEOF
Definition grammar.c:168
@ YYSYMBOL_subgraph
Definition grammar.c:218
@ YYSYMBOL_22_
Definition grammar.c:190
@ YYSYMBOL_optsubghdr
Definition grammar.c:220
@ YYSYMBOL_T_list
Definition grammar.c:178
@ YYSYMBOL_graphattrdefs
Definition grammar.c:217
@ YYSYMBOL_T_strict
Definition grammar.c:176
@ YYSYMBOL_graphtype
Definition grammar.c:197
@ YYSYMBOL_node
Definition grammar.c:208
@ YYSYMBOL_YYEMPTY
Definition grammar.c:167
@ YYSYMBOL_simple
Definition grammar.c:203
@ YYSYMBOL_T_digraph
Definition grammar.c:174
@ YYSYMBOL_16_
Definition grammar.c:184
@ YYSYMBOL_attrdefs
Definition grammar.c:215
@ YYSYMBOL_38_2
Definition grammar.c:206
@ YYSYMBOL_optstrict
Definition grammar.c:196
#define YY_ASSERT(E)
Definition grammar.c:419
#define YY_(Msgid)
Definition grammar.c:353
#define YYNOMEM
Definition grammar.c:774
#define YY_IGNORE_MAYBE_UNINITIALIZED_END
Definition grammar.c:400
static const yytype_int8 yydefact[]
Definition grammar.c:676
#define YYNSTATES
Definition grammar.c:560
static void applyattrs(aagextra_t *ctx, void *obj)
Definition grammar.c:1724
#define YYSTYPE
Definition grammar.c:67
#define YY_IGNORE_USELESS_CAST_END
Definition grammar.c:415
short yytype_int16
Definition grammar.c:264
static void appendnode(aagscan_t scanner, char *name, char *port, char *sport)
Definition grammar.c:1796
static char * concatPort(Agraph_t *G, char *, char *)
Definition grammar.c:1909
struct list_s list_t
#define YYABORT
Definition grammar.c:772
#define YYSTACK_BYTES(N)
Definition grammar.c:504
static const yytype_int8 yycheck[]
Definition grammar.c:719
static char * concat(aagscan_t scanner, char *, char *)
Definition grammar.c:1889
#define YY_REDUCE_PRINT(Rule)
Definition grammar.c:925
#define YY_CAST(Type, Val)
Definition grammar.c:147
static void deletelist(Agraph_t *G, list_t *list)
Definition grammar.c:1682
static void mkport(aagscan_t scanner, Agedge_t *e, char *name, char *val)
Definition grammar.c:1940
#define yylex
Definition grammar.c:70
#define YY_NULLPTR
Definition grammar.c:159
static const yytype_int8 yypact[]
Definition grammar.c:661
static item * cons_attr(char *name, char *value)
Definition grammar.c:1646
static void newedge(aagscan_t scanner, Agnode_t *t, char *tport, Agnode_t *h, char *hport, char *key)
Definition grammar.c:1952
#define YYFINAL
Definition grammar.c:549
#define YY_ACCESSING_SYMBOL(State)
Definition grammar.c:620
#define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
Definition grammar.c:923
#define YY_INITIAL_VALUE(Value)
Definition grammar.c:396
static void appendattr(aagscan_t scanner, char *name, char *value)
Definition grammar.c:1697
static void startgraph(aagscan_t scanner, char *name, bool directed, bool strict)
Definition grammar.c:1974
#define yyparse
Definition grammar.c:69
#define YYNTOKENS
Definition grammar.c:554
struct item_s item
unsigned char yytype_uint8
Definition grammar.c:285
#define YY_STACK_PRINT(Bottom, Top)
Definition grammar.c:924
#define YYSIZE_T
Definition grammar.c:326
static void delete_items(Agraph_t *G, item *ilist)
Definition grammar.c:1670
#define yydebug
Definition grammar.c:72
#define YY_IGNORE_USELESS_CAST_BEGIN
Definition grammar.c:414
static item * cons_subg(Agraph_t *subg)
Definition grammar.c:1652
static const yytype_int8 yyr2[]
Definition grammar.c:755
void * malloc(YYSIZE_T)
static const yytype_int8 yytable[]
Definition grammar.c:709
#define YYPTRDIFF_T
Definition grammar.c:312
#define yynerrs
Definition grammar.c:73
@ YYENOMEM
Definition grammar.c:766
static item * cons_node(Agnode_t *n, char *port)
Definition grammar.c:1643
#define YYACCEPT
Definition grammar.c:771
#define yytable_value_is_error(Yyn)
Definition grammar.c:656
static void freestack(aagscan_t scanner)
Definition grammar.c:2014
struct gstack_s gstack_t
#define YYTRANSLATE(YYX)
Definition grammar.c:568
static item * cons_list(item *list)
Definition grammar.c:1649
static const yytype_int8 yystos[]
Definition grammar.c:731
static void closesubg(aagscan_t scanner)
Definition grammar.c:2003
#define YY_ATTRIBUTE_UNUSED
Definition grammar.c:370
static const yytype_int8 yypgoto[]
Definition grammar.c:689
static void endnode(aagscan_t scanner)
Definition grammar.c:1816
static const yytype_int8 yyr1[]
Definition grammar.c:744
static item * newitem(int tag, void *p0, char *p1)
Definition grammar.c:1634
static void endedge(aagscan_t scanner)
Definition grammar.c:1849
#define YYPOPSTACK(N)
static void listapp(list_t *list, item *v)
Definition grammar.c:1688
int yy_state_fast_t
Definition grammar.c:343
union s val_t
unsigned short yytype_uint16
Definition grammar.c:296
static const yytype_int8 yydefgoto[]
Definition grammar.c:698
static void edgerhs(aagscan_t scanner, Agnode_t *n, char *tport, item *hlist, char *key)
Definition grammar.c:1922
static void graph_error(aagscan_t scanner)
Definition grammar.c:2025
#define YYLAST
Definition grammar.c:551
#define YYSTACK_RELOCATE(Stack_alloc, Stack)
Definition grammar.c:515
#define yypact_value_is_default(Yyn)
Definition grammar.c:651
#define YYINITDEPTH
Definition grammar.c:931
static void getedgeitems(aagscan_t scanner)
Definition grammar.c:1834
signed char yytype_int8
Definition grammar.c:256
void free(void *)
#define YYERROR
Definition grammar.c:773
#define YYSIZEOF(X)
Definition grammar.c:336
#define YYSTACK_ALLOC
Definition grammar.c:460
static void nomacros(void)
Definition grammar.c:1746
yytype_int8 yy_state_t
Definition grammar.c:340
#define YYDPRINTF(Args)
Definition grammar.c:922
static void endgraph(aagscan_t scanner)
Definition grammar.c:1986
#define YY_USE(E)
Definition grammar.c:376
#define yyerror
Definition grammar.c:71
#define T_node
Definition grammar.h:113
#define T_atom
Definition grammar.h:121
#define AAGerror
Definition grammar.h:110
#define T_attr
Definition grammar.h:120
#define AAGEMPTY
Definition grammar.h:108
#define T_subgraph
Definition grammar.h:116
#define AAGUNDEF
Definition grammar.h:111
#define T_edge
Definition grammar.h:114
#define AAGEOF
Definition grammar.h:109
#define T_graph
Definition grammar.h:112
#define T_list
Definition grammar.h:119
node NULL
Definition grammar.y:181
void aginternalmapclearlocalnames(Agraph_t *g)
Definition imap.c:165
Agsym_t * agattr_text(Agraph_t *g, int kind, char *name, const char *value)
creates or looks up text attributes of a graph
Definition attr.c:334
int agxset(void *obj, Agsym_t *sym, const char *value)
Definition attr.c:522
int agxset_html(void *obj, Agsym_t *sym, const char *value)
Definition attr.c:541
Agsym_t * agattr_html(Agraph_t *g, int kind, char *name, const char *value)
agattr_text, but creates HTML-like values
Definition attr.c:338
Agdisc_t AgDefaultDisc
Definition graph.c:275
Agedge_t * agedge(Agraph_t *g, Agnode_t *t, Agnode_t *h, char *name, int createflag)
Definition edge.c:253
#define TAILPORT_ID
Definition cgraph.h:995
#define HEADPORT_ID
Definition cgraph.h:996
#define agtail(e)
Definition cgraph.h:988
#define aghead(e)
Definition cgraph.h:989
void agwarningf(const char *fmt,...)
Definition agerror.c:173
void agerrorf(const char *fmt,...)
Definition agerror.c:165
int agclose(Agraph_t *g)
deletes a graph, freeing its associated storage
Definition graph.c:95
Agraph_t * agconcat(Agraph_t *g, const char *filename, void *chan, Agdisc_t *disc)
merges the file contents with a pre-existing graph
Definition grammar.c:2036
Agraph_t * agopen(char *name, Agdesc_t desc, Agdisc_t *disc)
creates a new graph with the given name and kind
Definition graph.c:42
Agraph_t * agread(void *fp, Agdisc_t *disc)
constructs a new graph
Definition grammar.c:2058
Agnode_t * agnode(Agraph_t *g, char *name, int createflag)
Definition node.c:141
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition node.c:48
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:41
Agnode_t * agsubnode(Agraph_t *g, Agnode_t *n, int createflag)
Definition node.c:252
#define AGTYPE(obj)
returns AGRAPH, AGNODE, or AGEDGE depending on the type of the object
Definition cgraph.h:216
@ AGOUTEDGE
Definition cgraph.h:207
@ AGEDGE
Definition cgraph.h:207
@ AGNODE
Definition cgraph.h:207
@ AGINEDGE
Definition cgraph.h:207
@ AGRAPH
Definition cgraph.h:207
int aghtmlstr(const char *)
Definition refstr.c:438
int agstrfree(Agraph_t *, const char *, bool is_html)
Definition refstr.c:415
char * agstrdup(Agraph_t *, const char *)
returns a pointer to a reference-counted copy of the argument string, creating one if necessary
Definition refstr.c:399
Agraph_t * agsubg(Agraph_t *g, char *name, int cflag)
Definition subg.c:53
Arithmetic helper functions.
#define SWAP(a, b)
Definition gv_math.h:131
textitem scanner parser str
Definition htmlparse.y:218
cleanup & scanner
Definition htmlparse.y:289
NEATOPROCS_API void s1(graph_t *, node_t *)
Definition stuff.c:663
static bool streq(const char *a, const char *b)
are a and b equal?
Definition streq.h:11
graph descriptor
Definition cgraph.h:284
unsigned directed
Definition cgraph.h:285
user's discipline
Definition cgraph.h:336
graph or subgraph
Definition cgraph.h:424
string attribute descriptor symbol in Agattr_s.dict
Definition cgraph.h:651
unsigned char print
Definition cgraph.h:658
Agraph_t * G
Definition grammar.h:67
int SubgraphDepth
Definition grammar.h:69
agxbuf Sbuf
Definition grammar.h:78
Agdisc_t * Disc
Definition grammar.h:65
agxbuf InputFileBuffer
Definition grammar.h:75
struct gstack_s * S
Definition grammar.h:70
list_t attrlist
Definition grammar.c:114
list_t edgelist
Definition grammar.c:114
list_t nodelist
Definition grammar.c:114
Agraph_t * g
Definition grammar.c:112
Agraph_t * subg
Definition grammar.c:113
struct gstack_s * down
Definition grammar.c:115
char * str
Definition grammar.c:102
val_t u
Definition grammar.c:101
struct item_s * next
Definition grammar.c:103
int tag
Definition grammar.c:100
Definition utils.c:751
item * last
Definition grammar.c:108
item * first
Definition grammar.c:107
Definition types.h:48
Definition grammar.c:90
Agedge_t * e
Definition grammar.c:93
Agraph_t * subg
Definition grammar.c:92
Agsym_t * asym
Definition grammar.c:94
Agnode_t * n
Definition grammar.c:91
struct item_s * list
Definition grammar.c:96
char * name
Definition grammar.c:95
#define UNREACHABLE()
Definition unreachable.h:30