Skip to content

Commit bf278b7

Browse files
hsutterzaucy
authored andcommitted
Fixed terse syntax bug reported in hsutter#741 comments
The code in this comment should now parse correctly: hsutter#741 (comment)
1 parent 7eba6dc commit bf278b7

File tree

4 files changed

+66
-38
lines changed

4 files changed

+66
-38
lines changed

regression-tests/test-results/version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
cppfront compiler v0.2.1 Build 8A09:1000
2+
cppfront compiler v0.2.1 Build 8A11:1259
33
Copyright(c) Herb Sutter All rights reserved
44

55
SPDX-License-Identifier: CC-BY-NC-ND-4.0

source/build.info

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"8A09:1000"
1+
"8A11:1259"

source/io.h

+59-33
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ auto starts_with_identifier_colon(std::string const& line)
346346
// braces_tracker: to track brace depth
347347
//
348348
// Normally we don't emit diagnostics for Cpp1 code, but we do for a
349-
// brace mismatch since we're relying on balanced { } to find Cpp2 code
349+
// brace mismatch since we're relying on balanced {()} to find Cpp2 code
350350
//
351351
class braces_tracker
352352
{
@@ -391,6 +391,7 @@ class braces_tracker
391391
}
392392
};
393393
std::vector<pre_if_depth_info> preprocessor = { {} }; // sentinel
394+
char current_open_type = ' ';
394395
std::vector<lineno_t> open_braces;
395396
std::vector<error_entry>& errors;
396397

@@ -399,28 +400,39 @@ class braces_tracker
399400
: errors{errors}
400401
{ }
401402

402-
// --- Brace matching functions - { and }
403+
// --- Brace matching functions - { and }, or ( and )
403404

404-
auto found_open_brace(lineno_t lineno) -> void {
405+
auto found_open_brace(lineno_t lineno, char brace) -> void {
405406
assert(std::ssize(preprocessor) > 0);
406-
open_braces.push_back(lineno);
407-
preprocessor.back().found_open_brace();
407+
if (open_braces.empty()) {
408+
current_open_type = brace;
409+
}
410+
if (current_open_type == brace) {
411+
open_braces.push_back(lineno);
412+
preprocessor.back().found_open_brace();
413+
}
408414
}
409415

410-
auto found_close_brace(source_position pos) -> void {
416+
auto found_close_brace(source_position pos, char brace) -> void {
411417
assert(std::ssize(preprocessor) > 0);
412418

413-
if (std::ssize(open_braces) < 1) {
414-
errors.emplace_back(
415-
pos,
416-
"closing } does not match a prior {"
417-
);
418-
}
419-
else {
420-
open_braces.pop_back();
421-
}
419+
if (
420+
(current_open_type == '{' && brace == '}')
421+
|| (current_open_type == '(' && brace == ')')
422+
)
423+
{
424+
if (std::ssize(open_braces) < 1) {
425+
errors.emplace_back(
426+
pos,
427+
"closing } does not match a prior {"
428+
);
429+
}
430+
else {
431+
open_braces.pop_back();
432+
}
422433

423-
preprocessor.back().found_close_brace();
434+
preprocessor.back().found_close_brace();
435+
}
424436
}
425437

426438
auto found_eof(source_position pos) const -> void {
@@ -471,7 +483,7 @@ class braces_tracker
471483
// braces_to_ignore() will be the positive number of those net open braces
472484
// that this loop will now throw away
473485
for (auto i = 0; i < preprocessor.back().braces_to_ignore(); ++i) {
474-
found_close_brace( source_position{} );
486+
found_close_brace( source_position{}, current_open_type == '{' ? '}' : ')' );
475487
}
476488

477489
preprocessor.pop_back();
@@ -638,12 +650,12 @@ auto process_cpp_line(
638650

639651
break;case '{':
640652
if (!in_literal()) {
641-
braces.found_open_brace(lineno);
653+
braces.found_open_brace(lineno, '{');
642654
}
643655

644656
break;case '}':
645657
if (!in_literal()) {
646-
braces.found_close_brace(source_position(lineno, i));
658+
braces.found_close_brace(source_position(lineno, i), '}');
647659
}
648660

649661
break;case '*':
@@ -703,34 +715,45 @@ auto process_cpp2_line(
703715

704716
auto prev = ' ';
705717
auto in_string_literal = false;
718+
auto in_char_literal = false;
706719

707-
for (auto i = colno_t{0}; i < ssize(line); ++i) {
708-
709-
if (in_comment) {
720+
for (auto i = colno_t{0}; i < ssize(line); ++i)
721+
{
722+
if (in_comment)
723+
{
710724
switch (line[i]) {
711725
break;case '/': if (prev == '*') { in_comment = false; }
712726
break;default: ;
713727
}
714-
} else if (in_string_literal) {
728+
}
729+
else if (in_string_literal)
730+
{
715731
switch (line[i]) {
716732
break;case '"': if (prev != '\\') { in_string_literal = false; }
717733
break;default: ;
718734
}
719735
}
720-
721-
else {
736+
else if (in_char_literal)
737+
{
722738
switch (line[i]) {
739+
break;case '\'': if (prev != '\\') { in_char_literal = false; }
740+
break;default: ;
741+
}
742+
}
743+
else
744+
{
745+
switch (line[i])
746+
{
747+
// For finding Cpp2 definition endings, count () as {}
723748
break;case '{':
724-
if (prev != '\'') { // ignore character literals
725-
braces.found_open_brace(lineno);
726-
}
749+
case '(':
750+
braces.found_open_brace( lineno, line[i] );
727751

728752
break;case '}':
729-
if (prev != '\'') { // ignore character literals
730-
braces.found_close_brace( source_position(lineno, i) );
731-
if (braces.current_depth() < 1) {
732-
found_end = true;
733-
}
753+
case ')':
754+
braces.found_close_brace( source_position(lineno, i), line[i]);
755+
if (braces.current_depth() < 1 && line[i] != ')') {
756+
found_end = true;
734757
}
735758

736759
break;case ';':
@@ -755,6 +778,9 @@ auto process_cpp2_line(
755778
break;case '"':
756779
if (prev != '\\') { in_string_literal = true; }
757780

781+
break;case '\'':
782+
if (prev != '\\') { in_char_literal = true; }
783+
758784
break;default: ;
759785
}
760786
}

source/parse.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -5877,6 +5877,7 @@ class parser
58775877

58785878
if (
58795879
check_arrow
5880+
&& !done()
58805881
&& curr().type() == lexeme::Arrow
58815882
)
58825883
{
@@ -7886,12 +7887,13 @@ class parser
78867887
deduced_type = true;
78877888
}
78887889

7889-
// If we've already validated that this is a function where the `->`
7890-
// is followed by a valid expression-statement, parse that again
7890+
// If we've already validated that this is a function where the parameter
7891+
// list is followed by a valid expression-statement, parse that again
7892+
// (requiring a semicolon as we validated when determining terse_no_equals)
78917893
if (n->terse_no_equals)
78927894
{
78937895
n->equal_sign = curr().position();
7894-
n->initializer = statement(semicolon_required, n->equal_sign);
7896+
n->initializer = statement(/*ignore semicolon_required*/ true, n->equal_sign);
78957897
assert( n->initializer && "ICE: should have already validated that there's a valid expression-statement here" );
78967898
}
78977899

0 commit comments

Comments
 (0)