1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 12:32:20 +02:00

Improved handling of parser errors with attributed elements

This commit is contained in:
Brian Fiete 2025-06-01 18:05:28 +02:00
parent 01cb9bf970
commit 8a07189594
3 changed files with 35 additions and 6 deletions

View file

@ -238,7 +238,7 @@ void BfReducer::AddErrorNode(BfAstNode* astNode, bool removeNode)
mSource->AddErrorNode(astNode); mSource->AddErrorNode(astNode);
if (removeNode) if (removeNode)
astNode->RemoveSelf(); astNode->RemoveSelf();
mLastErrorSrcEnd = astNode->mSrcEnd; mLastErrorSrcEnd = BF_MAX(mLastErrorSrcEnd, astNode->mSrcEnd);
} }
bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int endNode, int* retryNode, int* outEndNode, bool* couldBeExpr, bool* isGenericType, bool* isTuple) bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int endNode, int* retryNode, int* outEndNode, bool* couldBeExpr, bool* isGenericType, bool* isTuple)
@ -5837,13 +5837,20 @@ BfTypeReference* BfReducer::CreateTypeRefAfter(BfAstNode* astNode, CreateTypeRef
{ {
if (mLastErrorSrcEnd > startPos) if (mLastErrorSrcEnd > startPos)
{ {
// We added an error node and made progress // We added an error node and made progress
for (int checkIdx = mVisitorPos.mReadPos - 1; checkIdx >= startPos - 1; checkIdx--)
{
auto checkNode = mVisitorPos.Get(checkIdx);
if (checkNode->mSrcEnd <= mLastErrorSrcEnd)
break;
mVisitorPos.mReadPos = checkIdx;
}
} }
else else
{ {
BF_ASSERT(mVisitorPos.mReadPos == startPos); BF_ASSERT(mVisitorPos.mReadPos == startPos);
} mVisitorPos.mReadPos = startPos - 1;
mVisitorPos.mReadPos--; }
} }
return typeRef; return typeRef;
} }
@ -6055,9 +6062,19 @@ BfAttributeDirective* BfReducer::CreateAttributeDirective(BfTokenNode* startToke
if (!isHandled) if (!isHandled)
{ {
int prevReadPos = mVisitorPos.mReadPos;
auto typeRef = CreateTypeRefAfter(attributeDirective); auto typeRef = CreateTypeRefAfter(attributeDirective);
if (typeRef == NULL) if (typeRef == NULL)
{ {
if (mVisitorPos.mReadPos != prevReadPos)
{
AddErrorNode(attributeDirective);
auto curNode = mVisitorPos.GetCurrent();
if ((mSource != NULL) && (!mSource->HasPendingError(curNode)))
mSource->AddErrorNode(curNode);
return NULL;
}
auto nextNode = mVisitorPos.GetNext(); auto nextNode = mVisitorPos.GetNext();
if (BfTokenNode* endToken = BfNodeDynCast<BfTokenNode>(nextNode)) if (BfTokenNode* endToken = BfNodeDynCast<BfTokenNode>(nextNode))
{ {
@ -6067,7 +6084,7 @@ BfAttributeDirective* BfReducer::CreateAttributeDirective(BfTokenNode* startToke
MEMBER_SET(attributeDirective, mCtorCloseParen, endToken); MEMBER_SET(attributeDirective, mCtorCloseParen, endToken);
return attributeDirective; return attributeDirective;
} }
} }
return attributeDirective; return attributeDirective;
} }
@ -11118,7 +11135,7 @@ void BfReducer::HandleBlock(BfBlock* block, bool allowEndingExpression)
flags = (CreateStmtFlags)(flags | CreateStmtFlags_AllowUnterminatedExpression); flags = (CreateStmtFlags)(flags | CreateStmtFlags_AllowUnterminatedExpression);
auto statement = CreateStatement(node, flags); auto statement = CreateStatement(node, flags);
if ((statement == NULL) && (mSource != NULL)) if ((statement == NULL) && (mSource != NULL) && (!mSource->HasPendingError(node)))
statement = mSource->CreateErrorNode(node); statement = mSource->CreateErrorNode(node);
isDone = !mVisitorPos.MoveNext(); isDone = !mVisitorPos.MoveNext();

View file

@ -64,6 +64,17 @@ BfErrorNode* BfSource::CreateErrorNode(BfAstNode* astNode)
return errorNode; return errorNode;
} }
bool BfSource::HasPendingError(BfAstNode* astNode)
{
for (auto errorNode : mPendingErrorNodes)
{
if ((astNode->mSrcStart >= errorNode->mSrcStart) && (astNode->mSrcEnd <= errorNode->mSrcEnd))
return true;
}
return false;
}
void BfSource::AddErrorNode(BfAstNode* astNode) void BfSource::AddErrorNode(BfAstNode* astNode)
{ {
mPendingErrorNodes.push_back(CreateErrorNode(astNode)); mPendingErrorNodes.push_back(CreateErrorNode(astNode));

View file

@ -104,6 +104,7 @@ public:
virtual void HadSrcRealloc() {} virtual void HadSrcRealloc() {}
BfErrorNode* CreateErrorNode(BfAstNode* astNode); BfErrorNode* CreateErrorNode(BfAstNode* astNode);
bool HasPendingError(BfAstNode* astNode);
void AddErrorNode(BfAstNode* astNode); void AddErrorNode(BfAstNode* astNode);
int AllocChars(int charCount); int AllocChars(int charCount);
void FinishSideNodes(); void FinishSideNodes();