forked from OSchip/llvm-project
[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
This commit is contained in:
parent
3993c7a444
commit
07b7ff9838
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue