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;
case SWIG_TOKEN_ELLIPSIS:
return ELLIPSIS;
/* Look for multi-character sequences */
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 <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 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 BEGINFILE ENDOFFILE
%token ILLEGAL CONSTANT
@ -1671,7 +1671,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
%type <p> templateparameter ;
%type <id> templcpptype cpptype classkey classkeyopt access_specifier;
%type <node> base_specifier;
%type <str> ellipsis variadic;
%type <str> variadic;
%type <type> type rawtype type_right anon_bitfield_type decltype ;
%type <bases> base_list inherit raw_inherit;
%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);
}
}
| PERIOD PERIOD PERIOD {
| ELLIPSIS {
SwigType *t = NewString("v(...)");
$$ = NewParmWithoutFileLineInfo(t, 0);
previousNode = currentNode;
@ -5500,16 +5500,16 @@ declarator : pointer notso_direct_declarator {
/* Variadic versions eg. MyClasses&... myIds */
| pointer PERIOD PERIOD PERIOD notso_direct_declarator {
$$ = $5;
| pointer ELLIPSIS notso_direct_declarator {
$$ = $3;
if ($$.type) {
SwigType_push($1,$$.type);
Delete($$.type);
}
$$.type = $1;
}
| pointer AND PERIOD PERIOD PERIOD notso_direct_declarator {
$$ = $6;
| pointer AND ELLIPSIS notso_direct_declarator {
$$ = $4;
SwigType_add_reference($1);
if ($$.type) {
SwigType_push($1,$$.type);
@ -5517,8 +5517,8 @@ declarator : pointer notso_direct_declarator {
}
$$.type = $1;
}
| pointer LAND PERIOD PERIOD PERIOD notso_direct_declarator {
$$ = $6;
| pointer LAND ELLIPSIS notso_direct_declarator {
$$ = $4;
SwigType_add_rvalue_reference($1);
if ($$.type) {
SwigType_push($1,$$.type);
@ -5526,34 +5526,34 @@ declarator : pointer notso_direct_declarator {
}
$$.type = $1;
}
| PERIOD PERIOD PERIOD direct_declarator {
$$ = $4;
| ELLIPSIS direct_declarator {
$$ = $2;
if (!$$.type) $$.type = NewStringEmpty();
}
| AND PERIOD PERIOD PERIOD notso_direct_declarator {
$$ = $5;
| AND ELLIPSIS notso_direct_declarator {
$$ = $3;
$$.type = NewStringEmpty();
SwigType_add_reference($$.type);
if ($5.type) {
SwigType_push($$.type,$5.type);
Delete($5.type);
if ($3.type) {
SwigType_push($$.type,$3.type);
Delete($3.type);
}
}
| LAND PERIOD PERIOD PERIOD notso_direct_declarator {
| LAND ELLIPSIS notso_direct_declarator {
/* Introduced in C++11, move operator && */
/* Adds one S/R conflict */
$$ = $5;
$$ = $3;
$$.type = NewStringEmpty();
SwigType_add_rvalue_reference($$.type);
if ($5.type) {
SwigType_push($$.type,$5.type);
Delete($5.type);
if ($3.type) {
SwigType_push($$.type,$3.type);
Delete($3.type);
}
}
| idcolon DSTAR PERIOD PERIOD PERIOD notso_direct_declarator {
| idcolon DSTAR ELLIPSIS notso_direct_declarator {
SwigType *t = NewStringEmpty();
$$ = $6;
$$ = $4;
SwigType_add_memberpointer(t,$1);
if ($$.type) {
SwigType_push(t,$$.type);
@ -5561,9 +5561,9 @@ declarator : pointer notso_direct_declarator {
}
$$.type = t;
}
| pointer idcolon DSTAR PERIOD PERIOD PERIOD notso_direct_declarator {
| pointer idcolon DSTAR ELLIPSIS notso_direct_declarator {
SwigType *t = NewStringEmpty();
$$ = $7;
$$ = $5;
SwigType_add_memberpointer(t,$2);
SwigType_push($1,t);
if ($$.type) {
@ -5573,8 +5573,8 @@ declarator : pointer notso_direct_declarator {
$$.type = $1;
Delete(t);
}
| pointer idcolon DSTAR AND PERIOD PERIOD PERIOD notso_direct_declarator {
$$ = $8;
| pointer idcolon DSTAR AND ELLIPSIS notso_direct_declarator {
$$ = $6;
SwigType_add_memberpointer($1,$2);
SwigType_add_reference($1);
if ($$.type) {
@ -5583,8 +5583,8 @@ declarator : pointer notso_direct_declarator {
}
$$.type = $1;
}
| pointer idcolon DSTAR LAND PERIOD PERIOD PERIOD notso_direct_declarator {
$$ = $8;
| pointer idcolon DSTAR LAND ELLIPSIS notso_direct_declarator {
$$ = $6;
SwigType_add_memberpointer($1,$2);
SwigType_add_rvalue_reference($1);
if ($$.type) {
@ -5593,9 +5593,9 @@ declarator : pointer notso_direct_declarator {
}
$$.type = $1;
}
| idcolon DSTAR AND PERIOD PERIOD PERIOD notso_direct_declarator {
| idcolon DSTAR AND ELLIPSIS notso_direct_declarator {
SwigType *t = NewStringEmpty();
$$ = $7;
$$ = $5;
SwigType_add_memberpointer(t,$1);
SwigType_add_reference(t);
if ($$.type) {
@ -5604,9 +5604,9 @@ declarator : pointer notso_direct_declarator {
}
$$.type = t;
}
| idcolon DSTAR LAND PERIOD PERIOD PERIOD notso_direct_declarator {
| idcolon DSTAR LAND ELLIPSIS notso_direct_declarator {
SwigType *t = NewStringEmpty();
$$ = $7;
$$ = $5;
SwigType_add_memberpointer(t,$1);
SwigType_add_rvalue_reference(t);
if ($$.type) {
@ -6549,9 +6549,9 @@ exprsimple : exprnum {
$$.val = NewStringf("sizeof(%s)",SwigType_str($3,0));
$$.type = T_ULONG;
}
| SIZEOF PERIOD PERIOD PERIOD LPAREN type parameter_declarator RPAREN {
SwigType_push($6,$7.type);
$$.val = NewStringf("sizeof...(%s)",SwigType_str($6,0));
| SIZEOF ELLIPSIS LPAREN type parameter_declarator RPAREN {
SwigType_push($4,$5.type);
$$.val = NewStringf("sizeof...(%s)",SwigType_str($4,0));
$$.type = T_ULONG;
}
/* 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("...");
}
;
variadic : ellipsis {
$$ = $1;
}
| empty {
$$ = 0;
}
@ -6919,11 +6914,11 @@ templcpptype : CLASS {
$$ = (char *)"typename";
if (!inherit_list) last_cpptype = $$;
}
| CLASS PERIOD PERIOD PERIOD {
| CLASS ELLIPSIS {
$$ = (char *)"class...";
if (!inherit_list) last_cpptype = $$;
}
| TYPENAME PERIOD PERIOD PERIOD {
| TYPENAME ELLIPSIS {
$$ = (char *)"typename...";
if (!inherit_list) last_cpptype = $$;
}
@ -7129,8 +7124,8 @@ ctor_initializer : COLON mem_initializer_list
mem_initializer_list : mem_initializer
| mem_initializer_list COMMA mem_initializer
| mem_initializer PERIOD PERIOD PERIOD
| mem_initializer_list COMMA mem_initializer PERIOD PERIOD PERIOD
| mem_initializer ELLIPSIS
| mem_initializer_list COMMA mem_initializer ELLIPSIS
;
mem_initializer : idcolon LPAREN {

View file

@ -636,7 +636,7 @@ static int look(Scanner *s) {
}
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))
state = 8; /* A numerical value */
else
@ -1330,19 +1330,34 @@ static int look(Scanner *s) {
}
break;
/* A period or maybe a floating point number */
/* A period or an ellipsis or maybe a floating point number */
case 100:
if ((c = nextchar(s)) == 0)
return (0);
if (isdigit(c))
state = 81;
else if (c == '.')
state = 101;
else {
retract(s, 1);
return SWIG_TOKEN_PERIOD;
}
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 */
if ((c = nextchar(s)) == 0)
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_WSTRING 33 /* L"str" */
#define SWIG_TOKEN_WCHAR 34 /* L'c' */
#define SWIG_TOKEN_ELLIPSIS 35 /* ... */
#define SWIG_TOKEN_ILLEGAL 99
#define SWIG_TOKEN_ERROR -1