parseWithRecovery is the internal implementation shared by both public APIs. It expects a preprocessed []models.TokenWithSpan (output of preprocessTokens).
(tokens []models.TokenWithSpan)
| 177 | // parseWithRecovery is the internal implementation shared by both public APIs. |
| 178 | // It expects a preprocessed []models.TokenWithSpan (output of preprocessTokens). |
| 179 | func (p *Parser) parseWithRecovery(tokens []models.TokenWithSpan) ([]ast.Statement, []error) { |
| 180 | p.tokens = tokens |
| 181 | p.currentPos = 0 |
| 182 | if len(tokens) > 0 { |
| 183 | p.currentToken = tokens[0] |
| 184 | } |
| 185 | |
| 186 | statements := make([]ast.Statement, 0, 8) |
| 187 | errors := make([]error, 0, 4) |
| 188 | |
| 189 | for p.currentPos < len(tokens) && !p.isType(models.TokenTypeEOF) { |
| 190 | // Skip semicolons between statements |
| 191 | if p.isType(models.TokenTypeSemicolon) { |
| 192 | p.advance() |
| 193 | continue |
| 194 | } |
| 195 | |
| 196 | stmtStartPos := p.currentPos |
| 197 | stmt, err := p.parseStatement() |
| 198 | if err != nil { |
| 199 | // Create a ParseError with position info, preserving original error |
| 200 | loc := p.currentLocation() |
| 201 | pe := &ParseError{ |
| 202 | Msg: err.Error(), |
| 203 | TokenIdx: stmtStartPos, |
| 204 | Line: loc.Line, |
| 205 | Column: loc.Column, |
| 206 | Cause: err, |
| 207 | } |
| 208 | if stmtStartPos < len(tokens) { |
| 209 | pe.TokenType = tokens[stmtStartPos].Token.Type.String() |
| 210 | pe.Literal = tokens[stmtStartPos].Token.Value |
| 211 | } |
| 212 | errors = append(errors, pe) |
| 213 | // If parseStatement didn't advance (e.g., unrecognized keyword), |
| 214 | // advance at least one token to avoid infinite loops. |
| 215 | if p.currentPos == stmtStartPos { |
| 216 | p.advance() |
| 217 | } |
| 218 | p.synchronize() |
| 219 | } else { |
| 220 | statements = append(statements, stmt) |
| 221 | // Optionally consume semicolon after statement |
| 222 | if p.isType(models.TokenTypeSemicolon) { |
| 223 | p.advance() |
| 224 | } |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | return statements, errors |
| 229 | } |
no test coverage detected