Author: Haojian Wu Date: 2022-08-23T15:08:33+02:00 New Revision: edb8fb265990c3c4d0453d6b789554ccb5341123
URL: https://github.com/llvm/llvm-project/commit/edb8fb265990c3c4d0453d6b789554ccb5341123 DIFF: https://github.com/llvm/llvm-project/commit/edb8fb265990c3c4d0453d6b789554ccb5341123.diff LOG: [pseudo] Fix HeadsPartition is not initialized correctly. The bug was that if we recover from the token 0, we will make the Heads empty (Line646), which results no recovery being applied. Reviewed By: sammccall Differential Revision: https://reviews.llvm.org/D132388 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 8e4e6181eb2a6..3e7d5a5435807 100644 --- a/clang-tools-extra/pseudo/lib/GLR.cpp +++ b/clang-tools-extra/pseudo/lib/GLR.cpp @@ -31,7 +31,6 @@ Token::Index findRecoveryEndpoint(ExtensionID Strategy, Token::Index Begin, const TokenStream &Tokens, const Language &Lang) { assert(Strategy != 0); - assert(Begin > 0); if (auto S = Lang.RecoveryStrategies.lookup(Strategy)) return S(Begin, Tokens); return Token::Invalid; @@ -614,7 +613,7 @@ const ForestNode &glrParse(const ParseParams &Params, SymbolID StartSymbol, // Invariant: Heads is partitioned by source: {shifted | reduced}. // HeadsPartition is the index of the first head formed by reduction. // We use this to discard and recreate the reduced heads during recovery. - unsigned HeadsPartition = 0; + unsigned HeadsPartition = Heads.size(); std::vector<const GSS::Node *> NextHeads; auto MaybeGC = [&, Roots(std::vector<const GSS::Node *>{}), I(0u)]() mutable { assert(NextHeads.empty() && "Running GC at the wrong time!"); diff --git a/clang-tools-extra/pseudo/unittests/GLRTest.cpp b/clang-tools-extra/pseudo/unittests/GLRTest.cpp index 761b2c8db4aac..f361fb78247ac 100644 --- a/clang-tools-extra/pseudo/unittests/GLRTest.cpp +++ b/clang-tools-extra/pseudo/unittests/GLRTest.cpp @@ -652,6 +652,31 @@ TEST_F(GLRTest, RecoverUnrestrictedReduce) { "[ 1, end) └─word := <opaque>\n"); } +TEST_F(GLRTest, RecoveryFromStartOfInput) { + build(R"bnf( + _ := start [recover=Fallback] EOF + + start := IDENTIFIER + )bnf"); + TestLang.Table = LRTable::buildSLR(TestLang.G); + bool fallback_recovered = false; + auto fallback = [&](Token::Index Start, const TokenStream & Code) { + fallback_recovered = true; + return Code.tokens().size(); + }; + TestLang.RecoveryStrategies.try_emplace( + extensionID("Fallback"), + fallback); + clang::LangOptions LOptions; + TokenStream Tokens = cook(lex("?", LOptions), LOptions); + + const ForestNode &Parsed = + glrParse({Tokens, Arena, GSStack}, id("start"), TestLang); + EXPECT_TRUE(fallback_recovered); + EXPECT_EQ(Parsed.dumpRecursive(TestLang.G), + "[ 0, end) start := <opaque>\n"); +} + TEST_F(GLRTest, RepeatedRecovery) { // We require multiple steps of recovery at eof and then a reduction in order // to successfully parse. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits