[PATCH] D130511: [pseudo][wip] Eliminate simple-type-specifier ambiguities.

Haojian Wu via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 25 13:05:55 PDT 2022


hokein created this revision.
hokein added a reviewer: sammccall.
Herald added a project: All.
hokein requested review of this revision.
Herald added a subscriber: alextsao1999.
Herald added a project: clang-tools-extra.

The solution is to favor the longest possible nest-name-specifier, and
drop other alternatives by using the guard.

This is my attempt, this might not be a right approach, looking for initial
thoughts.

Motivated cases:

  Foo::Foo() {};
  // the constructor can be parsed as:
  //  - Foo ::Foo(); // where the first Foo is return-type, and ::Foo is the function declarator
  //  + Foo::Foo(); // where Foo::Foo is the function declarator



  void test() {
  
  // a very slow parsing case when there are many qualifers!
  X::Y::Z;
  // The statement can be parsed as:
  //  - X ::Y::Z; // ::Y::Z is the declarator
  //  - X::Y ::Z; // ::Z is the declarator
  //  + X::Y::Z;  // a declaration without declarator (X::Y::Z is decl-specifier-seq)
  //  + X::Y::Z;  // a qualifed-id expression
  }


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D130511

Files:
  clang-tools-extra/pseudo/lib/cxx/CXX.cpp
  clang-tools-extra/pseudo/lib/cxx/cxx.bnf


Index: clang-tools-extra/pseudo/lib/cxx/cxx.bnf
===================================================================
--- clang-tools-extra/pseudo/lib/cxx/cxx.bnf
+++ clang-tools-extra/pseudo/lib/cxx/cxx.bnf
@@ -370,11 +370,11 @@
 defining-type-specifier := enum-specifier
 defining-type-specifier-seq := defining-type-specifier
 defining-type-specifier-seq := defining-type-specifier defining-type-specifier-seq [guard]
-simple-type-specifier := nested-name-specifier_opt type-name
+simple-type-specifier := nested-name-specifier_opt type-name [guard]
 simple-type-specifier := nested-name-specifier TEMPLATE simple-template-id
 simple-type-specifier := decltype-specifier
 simple-type-specifier := placeholder-type-specifier
-simple-type-specifier := nested-name-specifier_opt template-name
+simple-type-specifier := nested-name-specifier_opt template-name [guard]
 simple-type-specifier := builtin-type
 builtin-type := CHAR
 builtin-type := CHAR8_T
Index: clang-tools-extra/pseudo/lib/cxx/CXX.cpp
===================================================================
--- clang-tools-extra/pseudo/lib/cxx/CXX.cpp
+++ clang-tools-extra/pseudo/lib/cxx/CXX.cpp
@@ -162,6 +162,10 @@
   return symbolToToken(P.Lookahead) != tok::kw_else;
 }
 
+bool guardNextTokenNotColCol(const GuardParams &P) {
+  return symbolToToken(P.Lookahead) != tok::coloncolon;
+}
+
 // Whether this e.g. decl-specifier contains an "exclusive" type such as a class
 // name, and thus can't combine with a second exclusive type.
 //
@@ -308,6 +312,16 @@
            selection_statement_0if_1constexpr_2l_paren_3condition_4r_paren_5statement,
        guardNextTokenNotElse},
 
+      {(RuleID)Rule::simple_type_specifier_0nested_name_specifier_1type_name,
+       guardNextTokenNotColCol},
+      {(RuleID)Rule::simple_type_specifier_0nested_name_specifier_1template_name,
+       guardNextTokenNotColCol},
+      {(RuleID)Rule::simple_type_specifier_0type_name,
+       guardNextTokenNotColCol},
+      {(RuleID)Rule::simple_type_specifier_0template_name,
+       guardNextTokenNotColCol
+      },
+
       // The grammar distinguishes (only) user-defined vs plain string literals,
       // where the clang lexer distinguishes (only) encoding types.
       {(RuleID)Rule::user_defined_string_literal_chunk_0string_literal,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D130511.447444.patch
Type: text/x-patch
Size: 2293 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220725/51edb599/attachment.bin>


More information about the cfe-commits mailing list