[clang-tools-extra] 07b7ff9 - [pseudo] Allow opaque nodes to represent terminals

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 26 04:58:06 PDT 2022


Author: Sam McCall
Date: 2022-07-26T13:56:26+02:00
New Revision: 07b7ff983837dbc20749682673d09992f71b0c59

URL: https://github.com/llvm/llvm-project/commit/07b7ff983837dbc20749682673d09992f71b0c59
DIFF: https://github.com/llvm/llvm-project/commit/07b7ff983837dbc20749682673d09992f71b0c59.diff

LOG: [pseudo] Allow opaque nodes to represent terminals

This allows incomplete code such as `namespace foo {` to be modeled as a
normal sequence with the missing } represented by an empty opaque node.

Differential Revision: https://reviews.llvm.org/D130551

Added: 
    

Modified: 
    clang-tools-extra/pseudo/lib/GLR.cpp
    clang-tools-extra/pseudo/unittests/GLRTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/pseudo/lib/GLR.cpp b/clang-tools-extra/pseudo/lib/GLR.cpp
index ab230accdf8f8..10a94860ffc98 100644
--- a/clang-tools-extra/pseudo/lib/GLR.cpp
+++ b/clang-tools-extra/pseudo/lib/GLR.cpp
@@ -182,9 +182,13 @@ void glrRecover(llvm::ArrayRef<const GSS::Node *> OldHeads,
   for (const PlaceholderRecovery *Option : BestOptions) {
     const ForestNode &Placeholder =
         Params.Forest.createOpaque(Option->Symbol, RecoveryRange->Begin);
-    const GSS::Node *NewHead = Params.GSStack.addNode(
-        *Lang.Table.getGoToState(Option->RecoveryNode->State, Option->Symbol),
-        &Placeholder, {Option->RecoveryNode});
+    LRTable::StateID OldState = Option->RecoveryNode->State;
+    LRTable::StateID NewState =
+        isToken(Option->Symbol)
+            ? *Lang.Table.getShiftState(OldState, Option->Symbol)
+            : *Lang.Table.getGoToState(OldState, Option->Symbol);
+    const GSS::Node *NewHead =
+        Params.GSStack.addNode(NewState, &Placeholder, {Option->RecoveryNode});
     NewHeads.push_back(NewHead);
   }
   TokenIndex = RecoveryRange->End;

diff  --git a/clang-tools-extra/pseudo/unittests/GLRTest.cpp b/clang-tools-extra/pseudo/unittests/GLRTest.cpp
index 5f87efec67044..7abf9295d1570 100644
--- a/clang-tools-extra/pseudo/unittests/GLRTest.cpp
+++ b/clang-tools-extra/pseudo/unittests/GLRTest.cpp
@@ -604,6 +604,28 @@ TEST_F(GLRTest, RecoveryEndToEnd) {
             "[  5, end) └─} := tok[5]\n");
 }
 
+TEST_F(GLRTest, RecoverTerminal) {
+  build(R"bnf(
+    _ := stmt
+
+    stmt := IDENTIFIER ; [recover=Skip]
+  )bnf");
+  TestLang.Table = LRTable::buildSLR(TestLang.G);
+  TestLang.RecoveryStrategies.try_emplace(
+      extensionID("Skip"),
+      [](Token::Index Start, const TokenStream &) { return Start + 1; });
+  clang::LangOptions LOptions;
+  TokenStream Tokens = cook(lex("foo", LOptions), LOptions);
+
+  const ForestNode &Parsed =
+      glrParse({Tokens, Arena, GSStack}, id("stmt"), TestLang);
+  EXPECT_EQ(Parsed.dumpRecursive(TestLang.G),
+            "[  0, end) stmt := IDENTIFIER ; [recover=Skip]\n"
+            "[  0,   1) ├─IDENTIFIER := tok[0]\n"
+            "[  1, end) └─; := <opaque>\n");
+}
+
+
 TEST_F(GLRTest, NoExplicitAccept) {
   build(R"bnf(
     _ := test


        


More information about the cfe-commits mailing list