From cb8d8bb9b6aec5b873e93d0bab91f0a4ab29d9b0 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 21 Feb 2013 15:58:05 +0100 Subject: [PATCH] value type: accept "->" in type tags 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 value.charptrVal> STRING %token value.intVal> INTEGER %token value.floatVal> REAL %type 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 bff3280a..cced97bf 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. */ @@ -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 diff --git a/src/scan-gram.l b/src/scan-gram.l index 58f6590b..cf8b220d 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; <> unexpected_eof (token_start, ">"); diff --git a/tests/types.at b/tests/types.at index b0c3a364..7cf0b23d 100644 --- a/tests/types.at +++ b/tests/types.at @@ -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 ival> '1' '2' + %printer { ]AT_SKEL_CC_IF([[yyoutput << $$]], + [[fprintf (yyo, "%d", $$)]])[; } ival> + ], + ['1' '2' + { + printf ("%d %d\n", $1, $ival>2); + free ($1); + free ($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"], -- 2.45.2