bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 3/6] value type: accept "->" in type tags


From: Akim Demaille
Subject: [PATCH 3/6] value type: accept "->" in type tags
Date: Sat, 23 Feb 2013 16:59:55 +0100

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 |  8 +++++---
 src/scan-gram.l |  2 +-
 tests/types.at  | 32 +++++++++++++++++++++++++++++++-
 3 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/src/scan-code.l b/src/scan-code.l
index 562f03c..b9840b1 100644
--- a/src/scan-code.l
+++ b/src/scan-code.l
@@ -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.  */
@@ -671,7 +672,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
diff --git a/src/scan-gram.l b/src/scan-gram.l
index 58f6590..cf8b220 100644
--- a/src/scan-gram.l
+++ b/src/scan-gram.l
@@ -572,7 +572,7 @@ eqopt    ([[:space:]]*=)?
     STRING_GROW;
   }
 
-  [^<>]+ STRING_GROW;
+  ([^<>]|->)+ STRING_GROW;
   "<"+   STRING_GROW; nesting += yyleng;
 
   <<EOF>>   unexpected_eof (token_start, ">");
diff --git a/tests/types.at b/tests/types.at
index bf9e111..901e4cc 100644
--- a/tests/types.at
+++ b/tests/types.at
@@ -30,7 +30,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
 
@@ -83,6 +83,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"],
-- 
1.8.1.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]