]> git.saurik.com Git - bison.git/commitdiff
value type: accept "->" in type tags
authorAkim Demaille <akim@lrde.epita.fr>
Thu, 21 Feb 2013 14:58:05 +0000 (15:58 +0100)
committerAkim Demaille <akim@lrde.epita.fr>
Tue, 9 Apr 2013 12:07:51 +0000 (14:07 +0200)
Provide a means to dereference pointers when defining tags.  One
example could be:

  %code requires
  {
    typedef struct ListElementType
    {
      union value
      {
        int intVal;
        float floatVal;
        char* charptrVal;
      } value;

      struct ListElementType* next;
    } ListElementType;
  }

  %union
  {
    ListElementType* list;
  }

  %token <list->value.charptrVal> STRING
  %token <list->value.intVal> INTEGER
  %token <list->value.floatVal> REAL
  %type <list> ElementList LiteralType

* src/scan-code.l, src/scan-gram.l: Accept "->" in tags.
* tests/types.at: Add more test cases to cover this case.

src/scan-code.l
src/scan-gram.l
tests/types.at

index bff3280a565d933568c6966c118c46d046b77d40..cced97bfeaac135080bd320f351395854390f09d 100644 (file)
@@ -78,8 +78,9 @@ static bool untyped_var_seen;
 
 /* POSIX says that a tag must be both an id and a C union member, but
    historically almost any character is allowed in a tag.  We disallow
-   NUL and newline, as this simplifies our implementation.  */
-tag      [^\0\n>]+
+   NUL and newline, as this simplifies our implementation.  We allow
+   "->" as a means to dereference a pointer.  */
+tag      ([^\0\n>]|->)+
 
 /* Zero or more instances of backslash-newline.  Following GCC, allow
    white space between the backslash and the newline.  */
@@ -595,7 +596,8 @@ fetch_type_name (char *cp, char const **type_name,
   if (*cp == '<')
     {
       *type_name = ++cp;
-      while (*cp != '>')
+      /* Series of non-'>' or "->".  */
+      while (*cp != '>' || cp[-1] == '-')
         ++cp;
 
       /* The '>' symbol will be later replaced by '\0'. Original
index 58f6590b6a9c1992a2403be62003995060520dfb..cf8b220d3a329479a700a8f912cf96b684882685 100644 (file)
@@ -572,7 +572,7 @@ eqopt    ([[:space:]]*=)?
     STRING_GROW;
   }
 
-  [^<>]+ STRING_GROW;
+  ([^<>]|->)+ STRING_GROW;
   "<"+   STRING_GROW; nesting += yyleng;
 
   <<EOF>>   unexpected_eof (token_start, ">");
index b0c3a3641e851d1712f1c404ab7f1ee091a92bca..7cf0b23dbf57182b43b0f5651c9c196942525202 100644 (file)
@@ -53,7 +53,7 @@ m4_pushdef([AT_TEST],
 [
 AT_SETUP([$1])
 AT_KEYWORDS([api.value.type])
-AT_BISON_OPTION_PUSHDEFS([$1 $2])
+AT_BISON_OPTION_PUSHDEFS([%debug $1 $2])
 AT_DATA_GRAMMAR([test.y],
 [[%debug
 
@@ -106,6 +106,36 @@ m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]],
            AT_VAL.fval = (res - '0') / 10.f],
           [30 0.3])
 
+  # A user defined struct that uses pointers.
+  AT_TEST([%skeleton "]b4_skel["
+           %define api.value.type "struct bar"],
+          [%code requires
+           {
+             struct u
+             {
+               int ival;
+             };
+             struct bar
+             {
+               struct u *up;
+             };
+           }
+           %token <up->ival> '1' '2'
+           %printer { ]AT_SKEL_CC_IF([[yyoutput << $$]],
+                                     [[fprintf (yyo, "%d", $$)]])[; } <up->ival>
+           ],
+          ['1' '2'
+           {
+             printf ("%d %d\n", $1, $<up->ival>2);
+             free ($<up>1);
+             free ($<up>2);
+           }],
+          ["12"],
+          [AT_VAL.up = (struct u *) malloc (sizeof *AT_VAL.up);
+           assert (AT_VAL.up);
+           AT_VAL.up->ival = res - '0';],
+          [1 2])
+
   # A user defined union.
   AT_TEST([%skeleton "]b4_skel["
            %define api.value.type "union foo"],