Skip to content

Commit 6e0fffb

Browse files
committed
cpptoxml improve:
1. skip "..." (sizeof ...(Args)) 2. support template argument type "&&.." 3. ignore typedef decltype(...) Identifier
1 parent 359f76c commit 6e0fffb

File tree

3 files changed

+92
-26
lines changed

3 files changed

+92
-26
lines changed

cpptoxml/parser/lexer.cpp

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -580,10 +580,7 @@ void Lexer::scan_semicolon()
580580
{
581581
++cursor;
582582
token_stream[(int) index++].kind = ';';
583-
if (parse_template) {
584-
parse_template = false;
585-
parse_template_class = false;
586-
}
583+
handle_template_scope(';');
587584
}
588585

589586
void Lexer::scan_less()
@@ -611,12 +608,7 @@ void Lexer::scan_less()
611608
}
612609
else
613610
{
614-
if (parse_template_class) {
615-
token_stream[(int)index++].kind = '<';
616-
token_stream[(int)index++].kind = '<';
617-
} else {
618-
token_stream[(int)index++].kind = Token_shift;
619-
}
611+
token_stream[(int)index++].kind = Token_shift;
620612
}
621613
}
622614
else
@@ -669,7 +661,7 @@ void Lexer::scan_greater()
669661
}
670662
else
671663
{
672-
if (parse_template_class) {
664+
if (in_template_scope()) {
673665
token_stream[(int)index++].kind = '>';
674666
token_stream[(int)index++].kind = '>';
675667
} else {
@@ -724,10 +716,7 @@ void Lexer::scan_left_brace()
724716
{
725717
++cursor;
726718
token_stream[(int) index++].kind = '{';
727-
if (parse_template) {
728-
parse_template = false;
729-
parse_template_class = false;
730-
}
719+
handle_template_scope('{');
731720
}
732721

733722
void Lexer::scan_or()
@@ -758,6 +747,7 @@ void Lexer::scan_right_brace()
758747
{
759748
++cursor;
760749
token_stream[(int) index++].kind = '}';
750+
handle_template_scope('}');
761751
}
762752

763753
void Lexer::scan_tilde()
@@ -989,6 +979,7 @@ void Lexer::scanKeyword4()
989979
*(cursor + 3) == 'm')
990980
{
991981
token_stream[(int) index++].kind = Token_enum;
982+
handle_template_scope(Token_enum);
992983
return;
993984
}
994985
break;
@@ -1056,9 +1047,7 @@ void Lexer::scanKeyword5()
10561047
*(cursor + 4) == 's')
10571048
{
10581049
token_stream[(int) index++].kind = Token_class;
1059-
if (parse_template) {
1060-
parse_template_class = true;
1061-
}
1050+
handle_template_scope(Token_class);
10621051
return;
10631052
}
10641053
if (*(cursor + 1) == 'o' &&
@@ -1154,6 +1143,7 @@ void Lexer::scanKeyword5()
11541143
*(cursor + 4) == 'g')
11551144
{
11561145
token_stream[(int) index++].kind = Token_using;
1146+
handle_template_scope(Token_using);
11571147
return;
11581148
}
11591149
break;
@@ -1349,9 +1339,7 @@ void Lexer::scanKeyword6()
13491339
*(cursor + 5) == 't')
13501340
{
13511341
token_stream[(int) index++].kind = Token_struct;
1352-
if (parse_template) {
1353-
parse_template_class = true;
1354-
}
1342+
handle_template_scope(Token_struct);
13551343
return;
13561344
}
13571345
if (*(cursor + 1) == 'w' &&
@@ -1654,7 +1642,7 @@ void Lexer::scanKeyword8()
16541642
*(cursor + 7) == 'e')
16551643
{
16561644
token_stream[(int) index++].kind = Token_template;
1657-
parse_template = true;
1645+
handle_template_scope(Token_template);
16581646
return;
16591647
}
16601648
if (*(cursor + 1) == 'y' &&
@@ -1918,4 +1906,39 @@ void Lexer::scanKeyword16()
19181906
token_stream[(int) index++].kind = Token_identifier;
19191907
}
19201908

1909+
bool Lexer::in_template_scope() {
1910+
return parse_template_class;
1911+
}
1912+
1913+
void Lexer::handle_template_scope(int kind) {
1914+
switch (kind)
1915+
{
1916+
case Token_template: {
1917+
parse_template = true;
1918+
} break;
1919+
case ';': {
1920+
if (parse_template) {
1921+
parse_template = false;
1922+
parse_template_class = false;
1923+
}
1924+
} break;
1925+
case '{': {
1926+
} break;
1927+
case '}': {
1928+
if (parse_template) {
1929+
parse_template = false;
1930+
parse_template_class = false;
1931+
}
1932+
} break;
1933+
case Token_class:
1934+
case Token_struct:
1935+
case Token_enum:
1936+
case Token_using: {
1937+
if (parse_template) {
1938+
parse_template_class = true;
1939+
}
1940+
} break;
1941+
}
1942+
}
1943+
19211944
// kate: space-indent on; indent-width 2; replace-tabs on;

cpptoxml/parser/lexer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,9 @@ class Lexer
265265
void scan_tilde();
266266
void scan_EOF();
267267

268+
void handle_template_scope(int kind);
269+
bool in_template_scope();
270+
268271
private:
269272
Control *control;
270273
const unsigned char *cursor;

cpptoxml/parser/parser.cpp

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,9 @@ bool Parser::parseUsingTypeAlias(DeclarationAST *&node)
693693
return false;
694694
}
695695

696-
ADVANCE(';', ";");
696+
if (token_stream.lookAhead() == ';') {
697+
token_stream.nextToken();
698+
}
697699

698700
UsingTypeAliasAST *ast = CreateNode<UsingTypeAliasAST>(_M_pool);
699701
ast->name = name;
@@ -780,7 +782,22 @@ bool Parser::parseTypedef(DeclarationAST *&node)
780782
TypeSpecifierAST *spec = 0;
781783
if (!parseTypeSpecifierOrClassSpec(spec))
782784
{
783-
reportError(("Need a type specifier to declare"));
785+
// ignore typedef decltype(...) Identifier
786+
if (token_stream.lookAhead() == Token_decltype) {
787+
token_stream.nextToken();
788+
789+
if (skip('(', ')')) {
790+
token_stream.nextToken();
791+
}
792+
793+
if (token_stream.lookAhead() == Token_identifier) {
794+
token_stream.nextToken();
795+
return true;
796+
}
797+
798+
} else {
799+
reportError(("Need a type specifier to declare"));
800+
}
784801
return false;
785802
}
786803

@@ -1003,10 +1020,21 @@ bool Parser::parseSimpleTypeSpecifier(TypeSpecifierAST *&node,
10031020
case Token_float:
10041021
case Token_double:
10051022
case Token_void:
1023+
case Token_decltype: {
10061024
integrals = snoc(integrals, token_stream.cursor(), _M_pool);
10071025
isIntegral = true;
1008-
token_stream.nextToken();
1009-
break;
1026+
1027+
// skip "decltype(...)"
1028+
if (token_stream.lookAhead() == Token_decltype) {
1029+
token_stream.nextToken();
1030+
1031+
if (skip('(', ')')) {
1032+
token_stream.nextToken();
1033+
}
1034+
} else {
1035+
token_stream.nextToken();
1036+
}
1037+
} break;
10101038

10111039
default:
10121040
done = true;
@@ -1195,6 +1223,10 @@ bool Parser::parseDeclarator(DeclaratorAST *&node)
11951223
}
11961224
else
11971225
{
1226+
if (token_stream.lookAhead() == Token_ellipsis) {
1227+
token_stream.nextToken();
1228+
}
1229+
11981230
if (token_stream.lookAhead() == ':')
11991231
{
12001232
// unnamed bitfield
@@ -1786,6 +1818,9 @@ bool Parser::parseParameterDeclaration(ParameterDeclarationAST *&node)
17861818
token_stream.nextToken();
17871819
variadic = true;
17881820
}
1821+
else if (token_stream.lookAhead(1) == Token_ellipsis) {
1822+
variadic = true;
1823+
}
17891824

17901825
int index = (int) token_stream.cursor();
17911826

@@ -3817,6 +3852,11 @@ bool Parser::parseUnaryExpression(ExpressionAST *&node)
38173852
ast->sizeof_token = sizeof_token;
38183853

38193854
std::size_t index = token_stream.cursor();
3855+
// skip "..." (sizeof ...(Args))
3856+
if (token_stream.lookAhead() == Token_ellipsis) {
3857+
token_stream.nextToken();
3858+
}
3859+
38203860
if (token_stream.lookAhead() == '(')
38213861
{
38223862
token_stream.nextToken();

0 commit comments

Comments
 (0)