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.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D132470

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


Index: clang-tools-extra/pseudo/unittests/GLRTest.cpp
===================================================================
--- clang-tools-extra/pseudo/unittests/GLRTest.cpp
+++ clang-tools-extra/pseudo/unittests/GLRTest.cpp
@@ -708,6 +708,57 @@
             "[  1, end) └─body := <opaque>\n");
 }
 
+TEST_F(GLRTest, SpuriousRecoveryLeftAndUpwardsCase) {
+  build(R"bnf(
+    _ := compound-stmt EOF
+
+    compound-stmt := { stmt-seq [recover=Braces] }
+
+    stmt-seq := stmt
+    stmt-seq := stmt-seq stmt
+
+    stmt := compound-stmt
+    stmt := IF ( expr [recover=Parentheses] ) IDENTIFIER
+    stmt := ;
+  )bnf");
+
+  TestLang.Table = LRTable::buildSLR(TestLang.G);
+  TestLang.RecoveryStrategies.try_emplace(extensionID("Braces"), 
recoverBraces);
+  TestLang.RecoveryStrategies.try_emplace(
+      extensionID("Parentheses"),
+      [](Token::Index Start, const TokenStream &Code) {
+        assert(Start > 0);
+        const Token &Left = Code.tokens()[Start - 1];
+        assert(Left.Kind == tok::l_paren);
+        if (const auto *Right = Left.pair())
+          return Code.index(*Right);
+        return Token::Invalid;
+      });
+  clang::LangOptions LOptions;
+  TokenStream Tokens = cook(lex(R"cpp(
+   { ;
+     { if (id) ? }
+   }
+  )cpp", LOptions), LOptions);
+  pairBrackets(Tokens);
+
+  const ForestNode &Parsed =
+      glrParse({Tokens, Arena, GSStack}, id("compound-stmt"), TestLang);
+  EXPECT_EQ(Parsed.dumpRecursive(TestLang.G),
+            "[  0, end) compound-stmt := { stmt-seq [recover=Braces] }\n"
+            "[  0,   1) ├─{ := tok[0]\n"
+            "[  1,   9) ├─stmt-seq := stmt-seq stmt\n"
+            "[  1,   2) │ ├─stmt-seq := stmt\n"
+            "[  1,   2) │ │ └─stmt := ;\n"
+            "[  1,   2) │ │   └─; := tok[1]\n"
+            "[  2,   9) │ └─stmt := compound-stmt\n"
+            "[  2,   9) │   └─compound-stmt := { stmt-seq [recover=Braces] }\n"
+            "[  2,   3) │     ├─{ := tok[2]\n"
+            "[  3,   8) │     ├─stmt-seq := <opaque>\n"
+            "[  8,   9) │     └─} := tok[8]\n"
+            "[  9, end) └─} := tok[9]\n");
+}
+
 TEST_F(GLRTest, NoExplicitAccept) {
   build(R"bnf(
     _ := test EOF
Index: clang-tools-extra/pseudo/lib/GLR.cpp
===================================================================
--- clang-tools-extra/pseudo/lib/GLR.cpp
+++ clang-tools-extra/pseudo/lib/GLR.cpp
@@ -88,7 +88,6 @@
   // For now, we have to take this into account when defining recovery rules.
   // (e.g. in the expr recovery above, stay inside the parentheses).
   // FIXME: find a more satisfying way to avoid such false recovery.
-  // FIXME: Add a test for spurious recovery once tests can define strategies.
   std::vector<const ForestNode *> Path;
   llvm::DenseSet<const GSS::Node *> Seen;
   auto WalkUp = [&](const GSS::Node *N, Token::Index NextTok, auto &WalkUp) {


Index: clang-tools-extra/pseudo/unittests/GLRTest.cpp
===================================================================
--- clang-tools-extra/pseudo/unittests/GLRTest.cpp
+++ clang-tools-extra/pseudo/unittests/GLRTest.cpp
@@ -708,6 +708,57 @@
             "[  1, end) └─body := <opaque>\n");
 }
 
+TEST_F(GLRTest, SpuriousRecoveryLeftAndUpwardsCase) {
+  build(R"bnf(
+    _ := compound-stmt EOF
+
+    compound-stmt := { stmt-seq [recover=Braces] }
+
+    stmt-seq := stmt
+    stmt-seq := stmt-seq stmt
+
+    stmt := compound-stmt
+    stmt := IF ( expr [recover=Parentheses] ) IDENTIFIER
+    stmt := ;
+  )bnf");
+
+  TestLang.Table = LRTable::buildSLR(TestLang.G);
+  TestLang.RecoveryStrategies.try_emplace(extensionID("Braces"), recoverBraces);
+  TestLang.RecoveryStrategies.try_emplace(
+      extensionID("Parentheses"),
+      [](Token::Index Start, const TokenStream &Code) {
+        assert(Start > 0);
+        const Token &Left = Code.tokens()[Start - 1];
+        assert(Left.Kind == tok::l_paren);
+        if (const auto *Right = Left.pair())
+          return Code.index(*Right);
+        return Token::Invalid;
+      });
+  clang::LangOptions LOptions;
+  TokenStream Tokens = cook(lex(R"cpp(
+   { ;
+     { if (id) ? }
+   }
+  )cpp", LOptions), LOptions);
+  pairBrackets(Tokens);
+
+  const ForestNode &Parsed =
+      glrParse({Tokens, Arena, GSStack}, id("compound-stmt"), TestLang);
+  EXPECT_EQ(Parsed.dumpRecursive(TestLang.G),
+            "[  0, end) compound-stmt := { stmt-seq [recover=Braces] }\n"
+            "[  0,   1) ├─{ := tok[0]\n"
+            "[  1,   9) ├─stmt-seq := stmt-seq stmt\n"
+            "[  1,   2) │ ├─stmt-seq := stmt\n"
+            "[  1,   2) │ │ └─stmt := ;\n"
+            "[  1,   2) │ │   └─; := tok[1]\n"
+            "[  2,   9) │ └─stmt := compound-stmt\n"
+            "[  2,   9) │   └─compound-stmt := { stmt-seq [recover=Braces] }\n"
+            "[  2,   3) │     ├─{ := tok[2]\n"
+            "[  3,   8) │     ├─stmt-seq := <opaque>\n"
+            "[  8,   9) │     └─} := tok[8]\n"
+            "[  9, end) └─} := tok[9]\n");
+}
+
 TEST_F(GLRTest, NoExplicitAccept) {
   build(R"bnf(
     _ := test EOF
Index: clang-tools-extra/pseudo/lib/GLR.cpp
===================================================================
--- clang-tools-extra/pseudo/lib/GLR.cpp
+++ clang-tools-extra/pseudo/lib/GLR.cpp
@@ -88,7 +88,6 @@
   // For now, we have to take this into account when defining recovery rules.
   // (e.g. in the expr recovery above, stay inside the parentheses).
   // FIXME: find a more satisfying way to avoid such false recovery.
-  // FIXME: Add a test for spurious recovery once tests can define strategies.
   std::vector<const ForestNode *> Path;
   llvm::DenseSet<const GSS::Node *> Seen;
   auto WalkUp = [&](const GSS::Node *N, Token::Index NextTok, auto &WalkUp) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D132470: [pseudo] add t... Haojian Wu via Phabricator via cfe-commits

Reply via email to