mirror of https://github.com/swig/swig
Clean up parser rules for cpp_members
This simplifies the grammar rules and resolves some corner cases which currently failed to parse. This change: * Simplifies the grammar rules and handles some things in more appropriate places * fixes a parse error for a misplaced Doxygen comment which is the only thing in a class/struct. * fixes a parse error for %include/#include in a class/struct followed by a member declaration. * eliminates an instance of right recursion in the grammar, which the bison docs warn against due to O(n) stack use. See #2884
This commit is contained in:
parent
2947806421
commit
846d5d2286
|
@ -7,6 +7,14 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
||||||
Version 4.3.0 (in progress)
|
Version 4.3.0 (in progress)
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
2024-09-18: olly
|
||||||
|
Fix parse error for a misplaced Doxygen comment which is the only
|
||||||
|
thing in a class/struct.
|
||||||
|
|
||||||
|
2024-09-18: olly
|
||||||
|
Fix parse error for %include/#include in a class/struct followed
|
||||||
|
by a member declaration.
|
||||||
|
|
||||||
2024-09-16: olly
|
2024-09-16: olly
|
||||||
#2995 SWIG now has generic handling for converting integer and
|
#2995 SWIG now has generic handling for converting integer and
|
||||||
boolean literal values for use in target language code, replacing
|
boolean literal values for use in target language code, replacing
|
||||||
|
|
|
@ -183,6 +183,11 @@
|
||||||
int bbbb; //! not for bbbb value, is quietly ignored by Doxygen and SWIG
|
int bbbb; //! not for bbbb value, is quietly ignored by Doxygen and SWIG
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct OrphanedComment
|
||||||
|
{
|
||||||
|
/** Doxygen quietly ignores this; SWIG < 4.3.0 gave parse error. */
|
||||||
|
};
|
||||||
|
|
||||||
#include "doxygen_misc_constructs.h"
|
#include "doxygen_misc_constructs.h"
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
|
@ -33,3 +33,16 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
%include "inctest.h"
|
%include "inctest.h"
|
||||||
} MY_THINGS;
|
} MY_THINGS;
|
||||||
|
|
||||||
|
// Regression test: we failed to handle the case of a member after the include.
|
||||||
|
%{
|
||||||
|
struct MY_THINGS2 {
|
||||||
|
#include "inctest2.h"
|
||||||
|
int failed_before_swig_430;
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
struct MY_THINGS2 {
|
||||||
|
%include "inctest2.h"
|
||||||
|
int failed_before_swig_430;
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
int IntegerMember;
|
|
@ -1753,6 +1753,10 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
|
||||||
Parm *parms;
|
Parm *parms;
|
||||||
Parm *last;
|
Parm *last;
|
||||||
} pbuilder;
|
} pbuilder;
|
||||||
|
struct {
|
||||||
|
Node *node;
|
||||||
|
Node *last;
|
||||||
|
} nodebuilder;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Define special token END for end of input. */
|
/* Define special token END for end of input. */
|
||||||
|
@ -1832,6 +1836,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
|
||||||
/* C++ declarations */
|
/* C++ declarations */
|
||||||
%type <node> cpp_declaration cpp_class_decl cpp_forward_class_decl cpp_template_decl;
|
%type <node> cpp_declaration cpp_class_decl cpp_forward_class_decl cpp_template_decl;
|
||||||
%type <node> cpp_members cpp_member cpp_member_no_dox;
|
%type <node> cpp_members cpp_member cpp_member_no_dox;
|
||||||
|
%type <nodebuilder> cpp_members_builder;
|
||||||
%type <node> cpp_constructor_decl cpp_destructor_decl cpp_protection_decl cpp_conversion_operator cpp_static_assert;
|
%type <node> cpp_constructor_decl cpp_destructor_decl cpp_protection_decl cpp_conversion_operator cpp_static_assert;
|
||||||
%type <node> cpp_swig_directive cpp_template_possible cpp_opt_declarators ;
|
%type <node> cpp_swig_directive cpp_template_possible cpp_opt_declarators ;
|
||||||
%type <node> cpp_using_decl cpp_namespace_decl cpp_catch_decl cpp_lambda_decl;
|
%type <node> cpp_using_decl cpp_namespace_decl cpp_catch_decl cpp_lambda_decl;
|
||||||
|
@ -4841,44 +4846,52 @@ Printf(stdout, " Scope %s [creating single scope C++17 style]\n", scopename);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
cpp_members : cpp_member cpp_members[in] {
|
cpp_members : cpp_members_builder {
|
||||||
$$ = $cpp_member;
|
$$ = $cpp_members_builder.node;
|
||||||
/* Insert cpp_member (including any siblings) to the front of the cpp_members linked list */
|
|
||||||
if ($$) {
|
|
||||||
Node *p = $$;
|
|
||||||
Node *pp =0;
|
|
||||||
while (p) {
|
|
||||||
pp = p;
|
|
||||||
p = nextSibling(p);
|
|
||||||
}
|
|
||||||
set_nextSibling(pp,$in);
|
|
||||||
if ($in)
|
|
||||||
set_previousSibling($in, pp);
|
|
||||||
} else {
|
|
||||||
$$ = $in;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
| cpp_member DOXYGENSTRING /* Misplaced doxygen string after a member, quietly ignore, like Doxygen does */
|
|
||||||
| EXTEND LBRACE {
|
|
||||||
extendmode = 1;
|
|
||||||
if (cplus_mode != CPLUS_PUBLIC) {
|
|
||||||
Swig_error(cparse_file,cparse_line,"%%extend can only be used in a public section\n");
|
|
||||||
}
|
}
|
||||||
} cpp_members[extend_members] RBRACE {
|
| cpp_members_builder DOXYGENSTRING {
|
||||||
extendmode = 0;
|
/* Quietly ignore misplaced doxygen string after a member, like Doxygen does */
|
||||||
} cpp_members[in] {
|
$$ = $cpp_members_builder.node;
|
||||||
$$ = new_node("extend");
|
}
|
||||||
mark_nodes_as_extend($extend_members);
|
| %empty {
|
||||||
appendChild($$,$extend_members);
|
$$ = 0;
|
||||||
set_nextSibling($$,$in);
|
}
|
||||||
|
| DOXYGENSTRING {
|
||||||
|
/* Quietly ignore misplaced doxygen string in empty class, like Doxygen does */
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| error {
|
||||||
|
Swig_error(cparse_file, cparse_line, "Syntax error in input(3).\n");
|
||||||
|
Exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
cpp_members_builder : cpp_member {
|
||||||
|
$$.node = $$.last = $cpp_member;
|
||||||
|
}
|
||||||
|
| cpp_members_builder[in] cpp_member {
|
||||||
|
// Build a linked list in the order specified, but avoiding
|
||||||
|
// a right recursion rule because "Right recursion uses up
|
||||||
|
// space on the Bison stack in proportion to the number of
|
||||||
|
// elements in the sequence".
|
||||||
|
if ($cpp_member) {
|
||||||
|
if ($in.node) {
|
||||||
|
Node *last = $in.last;
|
||||||
|
/* Advance to the last sibling. */
|
||||||
|
for (Node *p = last; p; p = nextSibling(p)) {
|
||||||
|
last = p;
|
||||||
|
}
|
||||||
|
set_nextSibling(last, $cpp_member);
|
||||||
|
set_previousSibling($cpp_member, last);
|
||||||
|
$$.node = $in.node;
|
||||||
|
} else {
|
||||||
|
$$.node = $$.last = $cpp_member;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$$ = $in;
|
||||||
}
|
}
|
||||||
| include_directive
|
}
|
||||||
| %empty { $$ = 0;}
|
;
|
||||||
| error {
|
|
||||||
Swig_error(cparse_file,cparse_line,"Syntax error in input(3).\n");
|
|
||||||
Exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
/* ======================================================================
|
/* ======================================================================
|
||||||
* C++ Class members
|
* C++ Class members
|
||||||
|
@ -4914,6 +4927,7 @@ cpp_member_no_dox : c_declaration
|
||||||
| cpp_using_decl
|
| cpp_using_decl
|
||||||
| cpp_template_decl
|
| cpp_template_decl
|
||||||
| cpp_catch_decl
|
| cpp_catch_decl
|
||||||
|
| include_directive
|
||||||
| template_directive
|
| template_directive
|
||||||
| warn_directive
|
| warn_directive
|
||||||
| anonymous_bitfield { $$ = 0; }
|
| anonymous_bitfield { $$ = 0; }
|
||||||
|
@ -4930,6 +4944,17 @@ cpp_member : cpp_member_no_dox
|
||||||
$$ = $cpp_member_no_dox;
|
$$ = $cpp_member_no_dox;
|
||||||
set_comment($cpp_member_no_dox, $DOXYGENPOSTSTRING);
|
set_comment($cpp_member_no_dox, $DOXYGENPOSTSTRING);
|
||||||
}
|
}
|
||||||
|
| EXTEND LBRACE {
|
||||||
|
extendmode = 1;
|
||||||
|
if (cplus_mode != CPLUS_PUBLIC) {
|
||||||
|
Swig_error(cparse_file,cparse_line,"%%extend can only be used in a public section\n");
|
||||||
|
}
|
||||||
|
} cpp_members RBRACE {
|
||||||
|
extendmode = 0;
|
||||||
|
$$ = new_node("extend");
|
||||||
|
mark_nodes_as_extend($cpp_members);
|
||||||
|
appendChild($$, $cpp_members);
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
/* Possibly a constructor */
|
/* Possibly a constructor */
|
||||||
|
|
Loading…
Reference in New Issue