@@ -1518,12 +1518,28 @@ func (p *Parser) parseTryCatchStatement() (*ast.TryCatchStatement, error) {
15181518 }
15191519
15201520 // Parse statements until END TRY
1521- for p .curTok .Type != TokenEnd && p . curTok . Type != TokenEOF {
1521+ for p .curTok .Type != TokenEOF {
15221522 // Skip semicolons
15231523 if p .curTok .Type == TokenSemicolon {
15241524 p .nextToken ()
15251525 continue
15261526 }
1527+ // Check for END TRY (not END CONVERSATION)
1528+ if p .curTok .Type == TokenEnd {
1529+ if p .peekTok .Type == TokenConversation {
1530+ // It's END CONVERSATION, parse it
1531+ endConvStmt , err := p .parseEndConversationStatement ()
1532+ if err != nil {
1533+ return nil , err
1534+ }
1535+ if endConvStmt != nil {
1536+ stmt .TryStatements .Statements = append (stmt .TryStatements .Statements , endConvStmt )
1537+ }
1538+ continue
1539+ }
1540+ // It's END TRY, break
1541+ break
1542+ }
15271543 s , err := p .parseStatement ()
15281544 if err != nil {
15291545 return nil , err
@@ -1552,12 +1568,28 @@ func (p *Parser) parseTryCatchStatement() (*ast.TryCatchStatement, error) {
15521568 stmt .CatchStatements = & ast.StatementList {}
15531569
15541570 // Parse catch statements until END CATCH
1555- for p .curTok .Type != TokenEnd && p . curTok . Type != TokenEOF {
1571+ for p .curTok .Type != TokenEOF {
15561572 // Skip semicolons
15571573 if p .curTok .Type == TokenSemicolon {
15581574 p .nextToken ()
15591575 continue
15601576 }
1577+ // Check for END CATCH (not END CONVERSATION)
1578+ if p .curTok .Type == TokenEnd {
1579+ if p .peekTok .Type == TokenConversation {
1580+ // It's END CONVERSATION, parse it
1581+ endConvStmt , err := p .parseEndConversationStatement ()
1582+ if err != nil {
1583+ return nil , err
1584+ }
1585+ if endConvStmt != nil {
1586+ stmt .CatchStatements .Statements = append (stmt .CatchStatements .Statements , endConvStmt )
1587+ }
1588+ continue
1589+ }
1590+ // It's END CATCH, break
1591+ break
1592+ }
15611593 s , err := p .parseStatement ()
15621594 if err != nil {
15631595 return nil , err
@@ -1588,8 +1620,24 @@ func (p *Parser) parseBeginEndBlockStatementContinued() (*ast.BeginEndBlockState
15881620 StatementList : & ast.StatementList {},
15891621 }
15901622
1591- // Parse statements until END
1592- for p .curTok .Type != TokenEnd && p .curTok .Type != TokenEOF {
1623+ // Parse statements until END (but not END CONVERSATION)
1624+ for p .curTok .Type != TokenEOF {
1625+ // Check for END (not END CONVERSATION)
1626+ if p .curTok .Type == TokenEnd {
1627+ if p .peekTok .Type == TokenConversation {
1628+ // It's END CONVERSATION, parse it
1629+ endConvStmt , err := p .parseEndConversationStatement ()
1630+ if err != nil {
1631+ return nil , err
1632+ }
1633+ if endConvStmt != nil {
1634+ stmt .StatementList .Statements = append (stmt .StatementList .Statements , endConvStmt )
1635+ }
1636+ continue
1637+ }
1638+ // It's END (block terminator), break
1639+ break
1640+ }
15931641 s , err := p .parseStatement ()
15941642 if err != nil {
15951643 return nil , err
@@ -1620,8 +1668,24 @@ func (p *Parser) parseBeginEndBlockStatement() (*ast.BeginEndBlockStatement, err
16201668 StatementList : & ast.StatementList {},
16211669 }
16221670
1623- // Parse statements until END
1624- for p .curTok .Type != TokenEnd && p .curTok .Type != TokenEOF {
1671+ // Parse statements until END (but not END CONVERSATION)
1672+ for p .curTok .Type != TokenEOF {
1673+ // Check for END (not END CONVERSATION)
1674+ if p .curTok .Type == TokenEnd {
1675+ if p .peekTok .Type == TokenConversation {
1676+ // It's END CONVERSATION, parse it
1677+ endConvStmt , err := p .parseEndConversationStatement ()
1678+ if err != nil {
1679+ return nil , err
1680+ }
1681+ if endConvStmt != nil {
1682+ stmt .StatementList .Statements = append (stmt .StatementList .Statements , endConvStmt )
1683+ }
1684+ continue
1685+ }
1686+ // It's END (block terminator), break
1687+ break
1688+ }
16251689 s , err := p .parseStatement ()
16261690 if err != nil {
16271691 return nil , err
@@ -2845,8 +2909,21 @@ func (p *Parser) parseStatementList() (*ast.StatementList, error) {
28452909 continue
28462910 }
28472911
2848- // Check for END (end of BEGIN block or TRY/CATCH)
2912+ // Check for END (end of BEGIN block or TRY/CATCH, or END CONVERSATION statement )
28492913 if p .curTok .Type == TokenEnd {
2914+ // Look ahead to check if it's END CONVERSATION (a statement)
2915+ if p .peekTok .Type == TokenConversation {
2916+ // It's END CONVERSATION statement, parse it
2917+ stmt , err := p .parseEndConversationStatement ()
2918+ if err != nil {
2919+ return nil , err
2920+ }
2921+ if stmt != nil {
2922+ sl .Statements = append (sl .Statements , stmt )
2923+ }
2924+ continue
2925+ }
2926+ // Otherwise it's the end of a BEGIN block
28502927 break
28512928 }
28522929
@@ -9840,6 +9917,75 @@ func (p *Parser) parseEnableDisableTriggerStatement(enforcement string) (*ast.En
98409917 return stmt , nil
98419918}
98429919
9920+ // parseEndConversationStatement parses END CONVERSATION statements
9921+ func (p * Parser ) parseEndConversationStatement () (* ast.EndConversationStatement , error ) {
9922+ // Consume END
9923+ p .nextToken ()
9924+
9925+ // Expect CONVERSATION
9926+ if strings .ToUpper (p .curTok .Literal ) != "CONVERSATION" {
9927+ return nil , fmt .Errorf ("expected CONVERSATION after END, got %s" , p .curTok .Literal )
9928+ }
9929+ p .nextToken ()
9930+
9931+ stmt := & ast.EndConversationStatement {}
9932+
9933+ // Parse the conversation handle expression
9934+ expr , err := p .parseScalarExpression ()
9935+ if err != nil {
9936+ return nil , err
9937+ }
9938+ stmt .Conversation = expr
9939+
9940+ // Check for WITH clause
9941+ if p .curTok .Type == TokenWith {
9942+ p .nextToken ()
9943+
9944+ if strings .ToUpper (p .curTok .Literal ) == "CLEANUP" {
9945+ stmt .WithCleanup = true
9946+ p .nextToken ()
9947+ } else if strings .ToUpper (p .curTok .Literal ) == "ERROR" {
9948+ p .nextToken ()
9949+
9950+ // Expect =
9951+ if p .curTok .Type == TokenEquals {
9952+ p .nextToken ()
9953+ }
9954+
9955+ // Parse error code
9956+ errCode , err := p .parseScalarExpression ()
9957+ if err != nil {
9958+ return nil , err
9959+ }
9960+ stmt .ErrorCode = errCode
9961+
9962+ // Expect DESCRIPTION
9963+ if strings .ToUpper (p .curTok .Literal ) == "DESCRIPTION" {
9964+ p .nextToken ()
9965+
9966+ // Expect =
9967+ if p .curTok .Type == TokenEquals {
9968+ p .nextToken ()
9969+ }
9970+
9971+ // Parse error description
9972+ errDesc , err := p .parseScalarExpression ()
9973+ if err != nil {
9974+ return nil , err
9975+ }
9976+ stmt .ErrorDescription = errDesc
9977+ }
9978+ }
9979+ }
9980+
9981+ // Skip optional semicolon
9982+ if p .curTok .Type == TokenSemicolon {
9983+ p .nextToken ()
9984+ }
9985+
9986+ return stmt , nil
9987+ }
9988+
98439989// parseCreateWorkloadGroupStatement parses CREATE WORKLOAD GROUP statement.
98449990func (p * Parser ) parseCreateWorkloadGroupStatement () (* ast.CreateWorkloadGroupStatement , error ) {
98459991 // Consume WORKLOAD
0 commit comments