Skip to content

Commit

Permalink
C++23: labels at the end of compound statements
Browse files Browse the repository at this point in the history
  • Loading branch information
guwirth committed Sep 2, 2024
1 parent 0a8339b commit 8d13a91
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 33 deletions.
17 changes: 0 additions & 17 deletions cxx-squid/dox/diff-cpp20-cpp23_grammar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -141,23 +141,6 @@ requirement-seq:
requirement
requirement requirement-seq

**A.6 Statements [gram.stmt]**

label:
attribute-specifier-seqopt identifier :
attribute-specifier-seqopt case constant-expression :
attribute-specifier-seqopt default :

labeled-statement:
label statement

compound-statement:
{ statement-seqopt label-seqopt }

label-seq:
label
label-seq label

**A.7 Declarations [gram.dcl]**

declaration:
Expand Down
22 changes: 16 additions & 6 deletions cxx-squid/src/main/java/org/sonar/cxx/parser/CxxGrammarImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ public enum CxxGrammarImpl implements GrammarRuleKey {
expressionStatement,
compoundStatement,
statementSeq,
labelSeq,
condition,
label,
selectionStatement,
iterationStatement,
initStatement,
Expand Down Expand Up @@ -963,32 +965,40 @@ private static void statements(LexerfulGrammarBuilder b) {
)
);

b.rule(labeledStatement).is(
b.rule(label).is(
b.firstOf(
b.sequence(b.optional(attributeSpecifierSeq), IDENTIFIER, ":", statement), // C++
b.sequence(b.optional(attributeSpecifierSeq), IDENTIFIER, ":"), // C++
b.sequence(
b.optional(attributeSpecifierSeq), CxxKeyword.CASE, constantExpression,
b.firstOf(
b.sequence(":", statement), // C++
b.sequence("...", constantExpression, ":", statement) // EXTENSION: gcc's case range
":", // C++
b.sequence("...", constantExpression, ":") // EXTENSION: gcc's case range
)
),
b.sequence(b.optional(attributeSpecifierSeq), CxxKeyword.DEFAULT, ":", statement) // C++
b.sequence(b.optional(attributeSpecifierSeq), CxxKeyword.DEFAULT, ":") // C++
)
);

b.rule(labeledStatement).is(
label, statement
);

b.rule(expressionStatement).is(
b.optional(expression), ";" // C++
);

b.rule(compoundStatement).is(
"{", b.optional(statementSeq), "}" // C++
"{", b.optional(statementSeq), b.optional(labelSeq), "}" // C++
);

b.rule(statementSeq).is(
b.oneOrMore(statement) // C++
);

b.rule(labelSeq).is(
b.oneOrMore(label) // C++
);

b.rule(selectionStatement).is(
b.firstOf(
b.sequence(CxxKeyword.IF, b.optional(CxxKeyword.CONSTEXPR), "(", b.optional(initStatement), condition, ")",
Expand Down
31 changes: 21 additions & 10 deletions cxx-squid/src/test/java/org/sonar/cxx/parser/StatementTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,23 +97,23 @@ void selectionStatement_reallife() {
}

@Test
void labeledStatement() {
setRootRule(CxxGrammarImpl.labeledStatement);
void label() {
setRootRule(CxxGrammarImpl.label);

mockRule(CxxGrammarImpl.attributeSpecifierSeq);
mockRule(CxxGrammarImpl.statement);
mockRule(CxxGrammarImpl.constantExpression);

assertThatParser()
.matches("foo : statement")
.matches("attributeSpecifierSeq foo : statement")
.matches("case constantExpression : statement")
.matches("attributeSpecifierSeq case constantExpression : statement")
.matches("default : statement")
.matches("attributeSpecifierSeq default : statement")
.matches("foo :")
.matches("attributeSpecifierSeq foo :")
.matches("case constantExpression :")
.matches("attributeSpecifierSeq case constantExpression :")
.matches("default :")
.matches("attributeSpecifierSeq default :")
// EXTENSION: gcc's case range
.matches("case constantExpression ... constantExpression : statement")
.matches("attributeSpecifierSeq case constantExpression ... constantExpression : statement");
.matches("case constantExpression ... constantExpression :")
.matches("attributeSpecifierSeq case constantExpression ... constantExpression :");
}

@Test
Expand All @@ -127,6 +127,17 @@ void statementSeq() {
.matches("statement statement");
}

@Test
void labelSeq() {
setRootRule(CxxGrammarImpl.labelSeq);

mockRule(CxxGrammarImpl.label);

assertThatParser()
.matches("label")
.matches("label label");
}

@Test
void selectionStatement() {
setRootRule(CxxGrammarImpl.selectionStatement);
Expand Down
10 changes: 10 additions & 0 deletions cxx-squid/src/test/resources/parser/own/C++23/labels-at-the-end.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
void foo()
{
first: // allowed in C++, now also allowed in C
int x;

second: // allowed in both C++ and C
x = 1;

last: // C++23: now also allowed in C++
}

0 comments on commit 8d13a91

Please sign in to comment.