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