diff --git a/cxx-squid/src/main/java/org/sonar/cxx/api/CxxKeyword.java b/cxx-squid/src/main/java/org/sonar/cxx/api/CxxKeyword.java index 18a78be652..1fa0ab764b 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/api/CxxKeyword.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/api/CxxKeyword.java @@ -114,6 +114,8 @@ public enum CxxKeyword implements TokenType { OR_EQ("or_eq"), XOR("xor"), XOR_EQ("xor_eq"), + TYPEID("typeid"), + // C++/CLI keywords GCNEW("gcnew"); private final String value; diff --git a/cxx-squid/src/main/java/org/sonar/cxx/parser/CxxGrammarImpl.java b/cxx-squid/src/main/java/org/sonar/cxx/parser/CxxGrammarImpl.java index 4626c68c4e..2d6b0b04bf 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/parser/CxxGrammarImpl.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/parser/CxxGrammarImpl.java @@ -429,8 +429,9 @@ private static void expressions(LexerfulGrammarBuilder b) { b.rule(nestedNameSpecifier).is( b.firstOf( - b.sequence(b.optional("::"), typeName, "::"), - b.sequence(b.optional("::"), namespaceName, "::"), + "::", + b.sequence(typeName, "::"), + b.sequence(namespaceName, "::"), b.sequence(decltypeSpecifier, "::") ), b.zeroOrMore( @@ -470,12 +471,12 @@ private static void expressions(LexerfulGrammarBuilder b) { b.rule(postfixExpression).is( b.firstOf( + b.sequence(typenameSpecifier, "::", CxxKeyword.TYPEID ), + b.sequence(simpleTypeSpecifier, "::", CxxKeyword.TYPEID ), b.sequence(simpleTypeSpecifier, b.optional(cudaKernel), "(", b.optional(expressionList), ")"), b.sequence(simpleTypeSpecifier, bracedInitList), - b.sequence(simpleTypeSpecifier, "::", "typeid"), b.sequence(typenameSpecifier, b.optional(cudaKernel), "(", b.optional(expressionList), ")"), b.sequence(typenameSpecifier, bracedInitList), - b.sequence(typenameSpecifier, "::", "typeid"), primaryExpression, @@ -483,8 +484,10 @@ private static void expressions(LexerfulGrammarBuilder b) { b.sequence(CxxKeyword.STATIC_CAST, typeIdEnclosed, "(", expression, ")"), b.sequence(CxxKeyword.REINTERPRET_CAST, typeIdEnclosed, "(", expression, ")"), b.sequence(CxxKeyword.CONST_CAST, typeIdEnclosed, "(", expression, ")"), - b.sequence("typeid", "(", expression, ")"), - b.sequence("typeid", "(", typeId, ")") + b.sequence(CxxKeyword.TYPEID, "(", expression, ")"), + b.sequence(CxxKeyword.TYPEID, "(", typeId, ")") + + ), // postfixExpression [ expression ] @@ -502,6 +505,7 @@ private static void expressions(LexerfulGrammarBuilder b) { b.zeroOrMore( b.firstOf( b.sequence("[", expression, "]"), + b.sequence("[", bracedInitList, "]"), b.sequence("(", b.optional(expressionList), ")"), b.sequence(b.firstOf(".", "->"), b.firstOf(b.sequence(b.optional(CxxKeyword.TEMPLATE), idExpression), @@ -645,9 +649,9 @@ private static void statements(LexerfulGrammarBuilder b) { b.rule(statement).is( b.firstOf( - b.sequence(b.optional(attributeSpecifierSeq), compoundStatement), labeledStatement, b.sequence(b.optional(attributeSpecifierSeq), expressionStatement), + b.sequence(b.optional(attributeSpecifierSeq), compoundStatement), b.sequence(b.optional(attributeSpecifierSeq), ifStatement), b.sequence(b.optional(attributeSpecifierSeq), switchStatement), b.sequence(b.optional(attributeSpecifierSeq), iterationStatement), @@ -853,9 +857,8 @@ private static void declarations(LexerfulGrammarBuilder b) { CxxKeyword.FLOAT, CxxKeyword.DOUBLE, CxxKeyword.VOID, CxxKeyword.AUTO, decltypeSpecifier, - b.sequence(b.optional("::"), b.optional(nestedNameSpecifier), typeName), -// b.sequence(b.optional(b.firstOf(nestedNameSpecifier,"::")), typeName) - b.sequence(b.optional("::"), b.optional(nestedNameSpecifier), CxxKeyword.TEMPLATE, simpleTemplateId) + b.sequence(b.optional(nestedNameSpecifier), typeName), + b.sequence(nestedNameSpecifier, CxxKeyword.TEMPLATE, simpleTemplateId) ) ); @@ -868,7 +871,11 @@ private static void declarations(LexerfulGrammarBuilder b) { ) ); - b.rule(decltypeSpecifier).is(CxxKeyword.DECLTYPE, "(", expression, ")"); + b.rule(decltypeSpecifier).is( + b.firstOf( + b.sequence(CxxKeyword.DECLTYPE, "(", expression, ")"), + b.sequence(CxxKeyword.DECLTYPE, "(", CxxKeyword.AUTO, ")") + )); b.rule(elaboratedTypeSpecifier).is( b.firstOf( @@ -1557,8 +1564,11 @@ private static void templates(LexerfulGrammarBuilder b) { ); b.rule(typenameSpecifier).is( - CxxKeyword.TYPENAME, nestedNameSpecifier, - b.firstOf(b.sequence(b.optional(CxxKeyword.TEMPLATE), simpleTemplateId), IDENTIFIER)); + b.firstOf( + b.sequence(CxxKeyword.TYPENAME, nestedNameSpecifier, b.optional(CxxKeyword.TEMPLATE), simpleTemplateId), + b.sequence(CxxKeyword.TYPENAME, nestedNameSpecifier, IDENTIFIER), + IDENTIFIER) + ); b.rule(explicitInstantiation).is(b.optional(CxxKeyword.EXTERN), CxxKeyword.TEMPLATE, declaration); diff --git a/cxx-squid/src/test/java/org/sonar/cxx/api/CxxKeywordTest.java b/cxx-squid/src/test/java/org/sonar/cxx/api/CxxKeywordTest.java index 0d7278b9ea..ef7659b57f 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/api/CxxKeywordTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/api/CxxKeywordTest.java @@ -27,7 +27,7 @@ public class CxxKeywordTest { @Test public void test() { - assertThat(CxxKeyword.values()).hasSize(84); + assertThat(CxxKeyword.values()).hasSize(85); assertThat(CxxKeyword.keywordValues()).hasSize(CxxKeyword.values().length); } diff --git a/cxx-squid/src/test/java/org/sonar/cxx/parser/ExpressionTest.java b/cxx-squid/src/test/java/org/sonar/cxx/parser/ExpressionTest.java index 0f482480a2..70433047f7 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/parser/ExpressionTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/parser/ExpressionTest.java @@ -188,6 +188,7 @@ public void postfixExpression_reallife() { assertThat(p).matches("dynamic_cast(myop)->op()"); assertThat(p).matches("::foo()"); assertThat(p).matches("obj.foo()"); + assertThat(p).matches("typeid(int)"); assertThat(p).matches("G::typeid"); assertThat(p).matches("int::typeid");