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.
/* 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
/* 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. */
/* Zero or more instances of backslash-newline. Following GCC, allow
white space between the backslash and the newline. */
if (*cp == '<')
{
*type_name = ++cp;
if (*cp == '<')
{
*type_name = ++cp;
+ /* Series of non-'>' or "->". */
+ while (*cp != '>' || cp[-1] == '-')
++cp;
/* The '>' symbol will be later replaced by '\0'. Original
++cp;
/* The '>' symbol will be later replaced by '\0'. Original
+ ([^<>]|->)+ STRING_GROW;
"<"+ STRING_GROW; nesting += yyleng;
<<EOF>> unexpected_eof (token_start, ">");
"<"+ STRING_GROW; nesting += yyleng;
<<EOF>> unexpected_eof (token_start, ">");
[
AT_SETUP([$1])
AT_KEYWORDS([api.value.type])
[
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
AT_DATA_GRAMMAR([test.y],
[[%debug
AT_VAL.fval = (res - '0') / 10.f],
[30 0.3])
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"],
# A user defined union.
AT_TEST([%skeleton "]b4_skel["
%define api.value.type "union foo"],