Handle ellipsis as a token in the scanner

This is more correct (previously SWIG incorrectly accepted 3 periods
with whitespace between as an ellipsis) and helps avoid conflicts in
the grammar.
This commit is contained in:
Olly Betts 2022-01-26 12:31:52 +13:00
commit 98e1251772
4 changed files with 62 additions and 48 deletions

View file

@ -351,6 +351,9 @@ static int yylook(void) {
} }
break; break;
case SWIG_TOKEN_ELLIPSIS:
return ELLIPSIS;
/* Look for multi-character sequences */ /* Look for multi-character sequences */
case SWIG_TOKEN_RSTRING: case SWIG_TOKEN_RSTRING:

View file

@ -1596,7 +1596,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
%token <dtype> NUM_INT NUM_FLOAT NUM_UNSIGNED NUM_LONG NUM_ULONG NUM_LONGLONG NUM_ULONGLONG NUM_BOOL %token <dtype> NUM_INT NUM_FLOAT NUM_UNSIGNED NUM_LONG NUM_ULONG NUM_LONGLONG NUM_ULONGLONG NUM_BOOL
%token <intvalue> TYPEDEF %token <intvalue> TYPEDEF
%token <type> TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_WCHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_COMPLEX TYPE_TYPEDEF TYPE_RAW TYPE_NON_ISO_INT8 TYPE_NON_ISO_INT16 TYPE_NON_ISO_INT32 TYPE_NON_ISO_INT64 %token <type> TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_WCHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_COMPLEX TYPE_TYPEDEF TYPE_RAW TYPE_NON_ISO_INT8 TYPE_NON_ISO_INT16 TYPE_NON_ISO_INT32 TYPE_NON_ISO_INT64
%token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE PERIOD %token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE PERIOD ELLIPSIS
%token CONST_QUAL VOLATILE REGISTER STRUCT UNION EQUAL SIZEOF MODULE LBRACKET RBRACKET %token CONST_QUAL VOLATILE REGISTER STRUCT UNION EQUAL SIZEOF MODULE LBRACKET RBRACKET
%token BEGINFILE ENDOFFILE %token BEGINFILE ENDOFFILE
%token ILLEGAL CONSTANT %token ILLEGAL CONSTANT
@ -1671,7 +1671,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
%type <p> templateparameter ; %type <p> templateparameter ;
%type <id> templcpptype cpptype classkey classkeyopt access_specifier; %type <id> templcpptype cpptype classkey classkeyopt access_specifier;
%type <node> base_specifier; %type <node> base_specifier;
%type <str> ellipsis variadic; %type <str> variadic;
%type <type> type rawtype type_right anon_bitfield_type decltype ; %type <type> type rawtype type_right anon_bitfield_type decltype ;
%type <bases> base_list inherit raw_inherit; %type <bases> base_list inherit raw_inherit;
%type <dtype> definetype def_args etype default_delete deleted_definition explicit_default; %type <dtype> definetype def_args etype default_delete deleted_definition explicit_default;
@ -5155,7 +5155,7 @@ parm_no_dox : rawtype parameter_declarator {
Setattr($$,"value",$7.val); Setattr($$,"value",$7.val);
} }
} }
| PERIOD PERIOD PERIOD { | ELLIPSIS {
SwigType *t = NewString("v(...)"); SwigType *t = NewString("v(...)");
$$ = NewParmWithoutFileLineInfo(t, 0); $$ = NewParmWithoutFileLineInfo(t, 0);
previousNode = currentNode; previousNode = currentNode;
@ -5500,16 +5500,16 @@ declarator : pointer notso_direct_declarator {
/* Variadic versions eg. MyClasses&... myIds */ /* Variadic versions eg. MyClasses&... myIds */
| pointer PERIOD PERIOD PERIOD notso_direct_declarator { | pointer ELLIPSIS notso_direct_declarator {
$$ = $5; $$ = $3;
if ($$.type) { if ($$.type) {
SwigType_push($1,$$.type); SwigType_push($1,$$.type);
Delete($$.type); Delete($$.type);
} }
$$.type = $1; $$.type = $1;
} }
| pointer AND PERIOD PERIOD PERIOD notso_direct_declarator { | pointer AND ELLIPSIS notso_direct_declarator {
$$ = $6; $$ = $4;
SwigType_add_reference($1); SwigType_add_reference($1);
if ($$.type) { if ($$.type) {
SwigType_push($1,$$.type); SwigType_push($1,$$.type);
@ -5517,8 +5517,8 @@ declarator : pointer notso_direct_declarator {
} }
$$.type = $1; $$.type = $1;
} }
| pointer LAND PERIOD PERIOD PERIOD notso_direct_declarator { | pointer LAND ELLIPSIS notso_direct_declarator {
$$ = $6; $$ = $4;
SwigType_add_rvalue_reference($1); SwigType_add_rvalue_reference($1);
if ($$.type) { if ($$.type) {
SwigType_push($1,$$.type); SwigType_push($1,$$.type);
@ -5526,34 +5526,34 @@ declarator : pointer notso_direct_declarator {
} }
$$.type = $1; $$.type = $1;
} }
| PERIOD PERIOD PERIOD direct_declarator { | ELLIPSIS direct_declarator {
$$ = $4; $$ = $2;
if (!$$.type) $$.type = NewStringEmpty(); if (!$$.type) $$.type = NewStringEmpty();
} }
| AND PERIOD PERIOD PERIOD notso_direct_declarator { | AND ELLIPSIS notso_direct_declarator {
$$ = $5; $$ = $3;
$$.type = NewStringEmpty(); $$.type = NewStringEmpty();
SwigType_add_reference($$.type); SwigType_add_reference($$.type);
if ($5.type) { if ($3.type) {
SwigType_push($$.type,$5.type); SwigType_push($$.type,$3.type);
Delete($5.type); Delete($3.type);
} }
} }
| LAND PERIOD PERIOD PERIOD notso_direct_declarator { | LAND ELLIPSIS notso_direct_declarator {
/* Introduced in C++11, move operator && */ /* Introduced in C++11, move operator && */
/* Adds one S/R conflict */ /* Adds one S/R conflict */
$$ = $5; $$ = $3;
$$.type = NewStringEmpty(); $$.type = NewStringEmpty();
SwigType_add_rvalue_reference($$.type); SwigType_add_rvalue_reference($$.type);
if ($5.type) { if ($3.type) {
SwigType_push($$.type,$5.type); SwigType_push($$.type,$3.type);
Delete($5.type); Delete($3.type);
} }
} }
| idcolon DSTAR PERIOD PERIOD PERIOD notso_direct_declarator { | idcolon DSTAR ELLIPSIS notso_direct_declarator {
SwigType *t = NewStringEmpty(); SwigType *t = NewStringEmpty();
$$ = $6; $$ = $4;
SwigType_add_memberpointer(t,$1); SwigType_add_memberpointer(t,$1);
if ($$.type) { if ($$.type) {
SwigType_push(t,$$.type); SwigType_push(t,$$.type);
@ -5561,9 +5561,9 @@ declarator : pointer notso_direct_declarator {
} }
$$.type = t; $$.type = t;
} }
| pointer idcolon DSTAR PERIOD PERIOD PERIOD notso_direct_declarator { | pointer idcolon DSTAR ELLIPSIS notso_direct_declarator {
SwigType *t = NewStringEmpty(); SwigType *t = NewStringEmpty();
$$ = $7; $$ = $5;
SwigType_add_memberpointer(t,$2); SwigType_add_memberpointer(t,$2);
SwigType_push($1,t); SwigType_push($1,t);
if ($$.type) { if ($$.type) {
@ -5573,8 +5573,8 @@ declarator : pointer notso_direct_declarator {
$$.type = $1; $$.type = $1;
Delete(t); Delete(t);
} }
| pointer idcolon DSTAR AND PERIOD PERIOD PERIOD notso_direct_declarator { | pointer idcolon DSTAR AND ELLIPSIS notso_direct_declarator {
$$ = $8; $$ = $6;
SwigType_add_memberpointer($1,$2); SwigType_add_memberpointer($1,$2);
SwigType_add_reference($1); SwigType_add_reference($1);
if ($$.type) { if ($$.type) {
@ -5583,8 +5583,8 @@ declarator : pointer notso_direct_declarator {
} }
$$.type = $1; $$.type = $1;
} }
| pointer idcolon DSTAR LAND PERIOD PERIOD PERIOD notso_direct_declarator { | pointer idcolon DSTAR LAND ELLIPSIS notso_direct_declarator {
$$ = $8; $$ = $6;
SwigType_add_memberpointer($1,$2); SwigType_add_memberpointer($1,$2);
SwigType_add_rvalue_reference($1); SwigType_add_rvalue_reference($1);
if ($$.type) { if ($$.type) {
@ -5593,9 +5593,9 @@ declarator : pointer notso_direct_declarator {
} }
$$.type = $1; $$.type = $1;
} }
| idcolon DSTAR AND PERIOD PERIOD PERIOD notso_direct_declarator { | idcolon DSTAR AND ELLIPSIS notso_direct_declarator {
SwigType *t = NewStringEmpty(); SwigType *t = NewStringEmpty();
$$ = $7; $$ = $5;
SwigType_add_memberpointer(t,$1); SwigType_add_memberpointer(t,$1);
SwigType_add_reference(t); SwigType_add_reference(t);
if ($$.type) { if ($$.type) {
@ -5604,9 +5604,9 @@ declarator : pointer notso_direct_declarator {
} }
$$.type = t; $$.type = t;
} }
| idcolon DSTAR LAND PERIOD PERIOD PERIOD notso_direct_declarator { | idcolon DSTAR LAND ELLIPSIS notso_direct_declarator {
SwigType *t = NewStringEmpty(); SwigType *t = NewStringEmpty();
$$ = $7; $$ = $5;
SwigType_add_memberpointer(t,$1); SwigType_add_memberpointer(t,$1);
SwigType_add_rvalue_reference(t); SwigType_add_rvalue_reference(t);
if ($$.type) { if ($$.type) {
@ -6549,9 +6549,9 @@ exprsimple : exprnum {
$$.val = NewStringf("sizeof(%s)",SwigType_str($3,0)); $$.val = NewStringf("sizeof(%s)",SwigType_str($3,0));
$$.type = T_ULONG; $$.type = T_ULONG;
} }
| SIZEOF PERIOD PERIOD PERIOD LPAREN type parameter_declarator RPAREN { | SIZEOF ELLIPSIS LPAREN type parameter_declarator RPAREN {
SwigType_push($6,$7.type); SwigType_push($4,$5.type);
$$.val = NewStringf("sizeof...(%s)",SwigType_str($6,0)); $$.val = NewStringf("sizeof...(%s)",SwigType_str($4,0));
$$.type = T_ULONG; $$.type = T_ULONG;
} }
/* We don't support all valid expressions here currently - e.g. /* We don't support all valid expressions here currently - e.g.
@ -6822,14 +6822,9 @@ exprcompound : expr PLUS expr {
} }
; ;
ellipsis : PERIOD PERIOD PERIOD { variadic : ELLIPSIS {
$$ = NewString("..."); $$ = NewString("...");
} }
;
variadic : ellipsis {
$$ = $1;
}
| empty { | empty {
$$ = 0; $$ = 0;
} }
@ -6919,11 +6914,11 @@ templcpptype : CLASS {
$$ = (char *)"typename"; $$ = (char *)"typename";
if (!inherit_list) last_cpptype = $$; if (!inherit_list) last_cpptype = $$;
} }
| CLASS PERIOD PERIOD PERIOD { | CLASS ELLIPSIS {
$$ = (char *)"class..."; $$ = (char *)"class...";
if (!inherit_list) last_cpptype = $$; if (!inherit_list) last_cpptype = $$;
} }
| TYPENAME PERIOD PERIOD PERIOD { | TYPENAME ELLIPSIS {
$$ = (char *)"typename..."; $$ = (char *)"typename...";
if (!inherit_list) last_cpptype = $$; if (!inherit_list) last_cpptype = $$;
} }
@ -7129,8 +7124,8 @@ ctor_initializer : COLON mem_initializer_list
mem_initializer_list : mem_initializer mem_initializer_list : mem_initializer
| mem_initializer_list COMMA mem_initializer | mem_initializer_list COMMA mem_initializer
| mem_initializer PERIOD PERIOD PERIOD | mem_initializer ELLIPSIS
| mem_initializer_list COMMA mem_initializer PERIOD PERIOD PERIOD | mem_initializer_list COMMA mem_initializer ELLIPSIS
; ;
mem_initializer : idcolon LPAREN { mem_initializer : idcolon LPAREN {

View file

@ -636,7 +636,7 @@ static int look(Scanner *s) {
} }
else if (c == '.') else if (c == '.')
state = 100; /* Maybe a number, maybe just a period */ state = 100; /* Maybe a number, maybe ellipsis, just a period */
else if (isdigit(c)) else if (isdigit(c))
state = 8; /* A numerical value */ state = 8; /* A numerical value */
else else
@ -1330,19 +1330,34 @@ static int look(Scanner *s) {
} }
break; break;
/* A period or maybe a floating point number */ /* A period or an ellipsis or maybe a floating point number */
case 100: case 100:
if ((c = nextchar(s)) == 0) if ((c = nextchar(s)) == 0)
return (0); return (0);
if (isdigit(c)) if (isdigit(c))
state = 81; state = 81;
else if (c == '.')
state = 101;
else { else {
retract(s, 1); retract(s, 1);
return SWIG_TOKEN_PERIOD; return SWIG_TOKEN_PERIOD;
} }
break; break;
/* An ellipsis */
case 101:
if ((c = nextchar(s)) == 0)
return (0);
if (c == '.') {
return SWIG_TOKEN_ELLIPSIS;
} else {
retract(s, 2);
return SWIG_TOKEN_PERIOD;
}
break;
case 200: /* PLUS, PLUSPLUS, PLUSEQUAL */ case 200: /* PLUS, PLUSPLUS, PLUSEQUAL */
if ((c = nextchar(s)) == 0) if ((c = nextchar(s)) == 0)
return SWIG_TOKEN_PLUS; return SWIG_TOKEN_PLUS;

View file

@ -70,6 +70,7 @@ extern void Scanner_locator(Scanner *, String *loc);
#define SWIG_TOKEN_BOOL 32 /* true or false */ #define SWIG_TOKEN_BOOL 32 /* true or false */
#define SWIG_TOKEN_WSTRING 33 /* L"str" */ #define SWIG_TOKEN_WSTRING 33 /* L"str" */
#define SWIG_TOKEN_WCHAR 34 /* L'c' */ #define SWIG_TOKEN_WCHAR 34 /* L'c' */
#define SWIG_TOKEN_ELLIPSIS 35 /* ... */
#define SWIG_TOKEN_ILLEGAL 99 #define SWIG_TOKEN_ILLEGAL 99
#define SWIG_TOKEN_ERROR -1 #define SWIG_TOKEN_ERROR -1