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)
|
||||
===========================
|
||||
|
||||
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
|
||||
#2995 SWIG now has generic handling for converting integer and
|
||||
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
|
||||
};
|
||||
|
||||
struct OrphanedComment
|
||||
{
|
||||
/** Doxygen quietly ignores this; SWIG < 4.3.0 gave parse error. */
|
||||
};
|
||||
|
||||
#include "doxygen_misc_constructs.h"
|
||||
|
||||
%}
|
||||
|
|
|
@ -33,3 +33,16 @@ typedef struct {
|
|||
typedef struct {
|
||||
%include "inctest.h"
|
||||
} 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 *last;
|
||||
} pbuilder;
|
||||
struct {
|
||||
Node *node;
|
||||
Node *last;
|
||||
} nodebuilder;
|
||||
};
|
||||
|
||||
/* Define special token END for end of input. */
|
||||
|
@ -1832,6 +1836,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
|
|||
/* C++ declarations */
|
||||
%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 <nodebuilder> cpp_members_builder;
|
||||
%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_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_member;
|
||||
/* 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 : cpp_members_builder {
|
||||
$$ = $cpp_members_builder.node;
|
||||
}
|
||||
} cpp_members[extend_members] RBRACE {
|
||||
extendmode = 0;
|
||||
} cpp_members[in] {
|
||||
$$ = new_node("extend");
|
||||
mark_nodes_as_extend($extend_members);
|
||||
appendChild($$,$extend_members);
|
||||
set_nextSibling($$,$in);
|
||||
| cpp_members_builder DOXYGENSTRING {
|
||||
/* Quietly ignore misplaced doxygen string after a member, like Doxygen does */
|
||||
$$ = $cpp_members_builder.node;
|
||||
}
|
||||
| %empty {
|
||||
$$ = 0;
|
||||
}
|
||||
| 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
|
||||
|
@ -4914,6 +4927,7 @@ cpp_member_no_dox : c_declaration
|
|||
| cpp_using_decl
|
||||
| cpp_template_decl
|
||||
| cpp_catch_decl
|
||||
| include_directive
|
||||
| template_directive
|
||||
| warn_directive
|
||||
| anonymous_bitfield { $$ = 0; }
|
||||
|
@ -4930,6 +4944,17 @@ cpp_member : cpp_member_no_dox
|
|||
$$ = $cpp_member_no_dox;
|
||||
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 */
|
||||
|
|
Loading…
Reference in New Issue