]> granicus.if.org Git - graphviz/commitdiff
use Bison's api.prefix and Flex's prefix instead of name mangling in cgraph
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Tue, 25 Aug 2020 01:31:26 +0000 (18:31 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Wed, 2 Sep 2020 00:28:02 +0000 (17:28 -0700)
Related to !1523. Bison's api.prefix was introduced in 2.6, but switched to
using this bracing syntax in 3.0. Quoting from the Bison 3.0 release notes:

  ** Types of values for %define variables

  Bison used to make no difference between '%define foo bar' and '%define
  foo "bar"'.  The former is now called a 'keyword value', and the latter a
  'string value'.  A third kind was added: 'code values', such as '%define
  foo {bar}'.

  Keyword variables are used for fixed value sets, e.g.,

    %define lr.type lalr

  Code variables are used for value in the target language, e.g.,

    %define api.value.type {struct semantic_type}

  String variables are used remaining cases, e.g. file names.

The Flex option prefix was introduced in Flex 2.4.1 (November 1993) and then
stabilized around 2.5.2 (April 1995). It provides similar functionality:

  ‘-PPREFIX, --prefix=PREFIX, %option prefix="PREFIX"’

  changes the default ‘yy’ prefix used by flex for all globally-visible variable
  and function names to instead be ‘PREFIX’. For example, ‘--prefix=foo’ changes
  the name of yytext to footext. It also changes the name of the default output
  file from lex.yy.c to lex.foo.c.

It would have been nicer to split the lexer and parser changes into separate
commits. However, the MSBuild build does no name mangling here (see
lib/cgraph/cgraph.vcxproj), so changing one of these immediately broke the other
one there. On the positive side, this commit has the effect of realigning some
MSBuild outputs with the Autotools build, as the cgraph lexer and parser are now
aag-prefixed there as well.

lib/cgraph/Makefile.am
lib/cgraph/grammar.y
lib/cgraph/scan.l

index 2774c54e41a79a4052df1ce5b8b6703df0e3eb23..a524ebd4d94aa758e585d11dd1e56e833b21166b 100644 (file)
@@ -30,8 +30,8 @@ scan.o scan.lo: scan.c grammar.h
 
 scan.c: $(top_srcdir)/lib/cgraph/scan.l
        @LEX@ -i $(top_srcdir)/lib/cgraph/scan.l
-       @SED@ "s/yy/aag/g" < @LEX_OUTPUT_ROOT@.c > scan.c
-       rm @LEX_OUTPUT_ROOT@.c
+       @SED@ "s/yy/aag/g" < lex.aag.c > scan.c
+       rm lex.aag.c
 
 grammar.c: y.tab.c
        @SED@ "s/yy/aag/g" < y.tab.c > grammar.c
index 737b147fecabf74c50b30a0bc846bcf4dfadfda3..a743419bcccdf11f7b31b1fb69d6e8f76d28f565 100644 (file)
 
 %require "3.0"
 
+  /* By default, Bison emits a parser using symbols prefixed with "yy". Graphviz
+   * contains multiple Bison-generated parsers, so we alter this prefix to avoid
+   * symbol clashes.
+   */
+%define api.prefix {aag}
+
 %{
 
 #include <stdio.h>  /* SAFE */
 #include <cghdr.h>     /* SAFE */
-extern void yyerror(char *);   /* gets mapped to aagerror, see below */
+extern void aagerror(char *);
 
 #ifdef _WIN32
 #define gettxt(a,b)    (b)
@@ -593,15 +599,15 @@ static void freestack()
        }
 }
 
-extern FILE *yyin;
+extern FILE *aagin;
 Agraph_t *agconcat(Agraph_t *g, void *chan, Agdisc_t *disc)
 {
-       yyin = chan;
+       aagin = chan;
        G = g;
        Ag_G_global = NILgraph;
        Disc = (disc? disc :  &AgDefaultDisc);
        aglexinit(Disc, chan);
-       yyparse();
+       aagparse();
        if (Ag_G_global == NILgraph) aglexbad();
        return Ag_G_global;
 }
index 5961ee2d3165cbe0aa790a2e695aa31e222c107b..a80fe683d193be700780756ae3d4f2a551d22d6b 100644 (file)
 
 
 /* requires flex (i.e. not lex)  */
+
+  /* By default, Flex emits a lexer using symbols prefixed with "yy". Graphviz
+   * contains multiple Flex-generated lexers, so we alter this prefix to avoid
+   * symbol clashes.
+   */
+%option prefix="aag"
+
 %{
 #include <grammar.h>
 #include <cghdr.h>
@@ -75,12 +82,12 @@ static void addstr(char *src) {
 }
 
 static void endstr(void) {
-       yylval.str = (char*)agstrdup(Ag_G_global,Sbuf);
+       aaglval.str = (char*)agstrdup(Ag_G_global,Sbuf);
        *Sbuf = 0;
 }
 
 static void endstr_html(void) {
-       yylval.str = (char*)agstrdup_html(Ag_G_global,Sbuf);
+       aaglval.str = (char*)agstrdup_html(Ag_G_global,Sbuf);
        *Sbuf = 0;
 }
 
@@ -101,13 +108,13 @@ storeFileName (char* fname, int len)
 
 /* ppDirective:
  * Process a possible preprocessor line directive.
- * yytext = #.*
+ * aagtext = #.*
  */
 static void ppDirective (void)
 {
     int r, cnt, lineno;
     char buf[2];
-    char* s = yytext + 1;  /* skip initial # */
+    char* s = aagtext + 1;  /* skip initial # */
 
     if (strncmp(s, "line", 4) == 0) s += 4;
     r = sscanf(s, "%d %1[\"]%n", &lineno, buf, &cnt);
@@ -132,8 +139,8 @@ static void ppDirective (void)
 static int twoDots(void)
 {
     int i;
-    for (i = yyleng-2; i >= 0; i--) {
-       if (((unsigned char)yytext[i]) == '.')
+    for (i = aagleng-2; i >= 0; i--) {
+       if (((unsigned char)aagtext[i]) == '.')
            return 1;
     }
     return 0;
@@ -145,7 +152,7 @@ static int twoDots(void)
  * or something like 123.456.78, and report this to the user.
  */
 static int chkNum(void) {
-    unsigned char c = (unsigned char)yytext[yyleng-1];   /* last character */
+    unsigned char c = (unsigned char)aagtext[aagleng-1];   /* last character */
     if ((!isdigit(c) && (c != '.')) || ((c == '.') && twoDots())) {  /* c is letter */
        char* fname;
 
@@ -155,7 +162,7 @@ static int chkNum(void) {
            fname = "input";
 
        agerr(AGWARN, "syntax ambiguity - badly delimited number '%s' in line %d of "
-         "%s splits into two tokens\n", yytext, line_num, fname);
+         "%s splits into two tokens\n", aagtext, line_num, fname);
 
        return 1;
     }
@@ -208,23 +215,23 @@ ID                ({NAME}|{NUMBER})
 "subgraph"                             return(T_subgraph);
 "->"                           if (graphType == T_digraph) return(T_edgeop); else return('-');
 "--"                           if (graphType == T_graph) return(T_edgeop); else return('-');
-{NAME}                                 { yylval.str = (char*)agstrdup(Ag_G_global,yytext); return(T_atom); }
-{NUMBER}                               { if (chkNum()) yyless(yyleng-1); yylval.str = (char*)agstrdup(Ag_G_global,yytext); return(T_atom); }
+{NAME}                                 { aaglval.str = (char*)agstrdup(Ag_G_global,aagtext); return(T_atom); }
+{NUMBER}                               { if (chkNum()) yyless(aagleng-1); aaglval.str = (char*)agstrdup(Ag_G_global,aagtext); return(T_atom); }
 ["]                                            BEGIN(qstring); beginstr();
 <qstring>["]                   BEGIN(INITIAL); endstr(); return (T_qatom);
 <qstring>[\\]["]               addstr ("\"");
 <qstring>[\\][\\]              addstr ("\\\\");
 <qstring>[\\][\n]              line_num++; /* ignore escaped newlines */
-<qstring>([^"\\]*|[\\])                addstr(yytext);
+<qstring>([^"\\]*|[\\])                addstr(aagtext);
 [<]                                            BEGIN(hstring); html_nest = 1; beginstr();
-<hstring>[>]                   html_nest--; if (html_nest) addstr(yytext); else {BEGIN(INITIAL); endstr_html(); return (T_qatom);}
-<hstring>[<]                   html_nest++; addstr(yytext);
-<hstring>[\n]                  addstr(yytext); line_num++; /* add newlines */
-<hstring>([^><\n]*)            addstr(yytext);
-.                                              return (yytext[0]);
+<hstring>[>]                   html_nest--; if (html_nest) addstr(aagtext); else {BEGIN(INITIAL); endstr_html(); return (T_qatom);}
+<hstring>[<]                   html_nest++; addstr(aagtext);
+<hstring>[\n]                  addstr(aagtext); line_num++; /* add newlines */
+<hstring>([^><\n]*)            addstr(aagtext);
+.                                              return (aagtext[0]);
 %%
  
-void yyerror(char *str)
+void aagerror(char *str)
 {
        unsigned char   xbuf[BUFSIZ];
        char    buf[BUFSIZ];
@@ -238,9 +245,9 @@ void yyerror(char *str)
        agxbput (&xb, str);
        sprintf(buf," in line %d", line_num);
        agxbput (&xb, buf);
-       if (*yytext) {
+       if (*aagtext) {
                agxbput(&xb," near '");
-               agxbput (&xb, yytext);
+               agxbput (&xb, aagtext);
                agxbputc (&xb, '\'');
        }
        else switch (YYSTATE) {
@@ -285,7 +292,7 @@ void aglexbad() { YY_FLUSH_BUFFER; }
 # define YY_CALL_ONLY_ARG void
 #endif
 
-int yywrap(YY_CALL_ONLY_ARG)
+int aagwrap(YY_CALL_ONLY_ARG)
 {
        return 1;
 }