or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-models.mdcode-generation.mdconfiguration.mdcore-parsing.mdexceptions.mdindex.mdsemantic-actions.mdtree-walking.md

exceptions.mddocs/

0

# Exception Handling

1

2

Comprehensive exception hierarchy for handling grammar compilation errors, parse failures, and semantic processing issues. TatSu provides detailed error information including position data, context, and recovery suggestions.

3

4

## Capabilities

5

6

### Base Exception Classes

7

8

Foundation exception classes that provide common functionality for all TatSu errors.

9

10

```python { .api }

11

class TatSuException(Exception):

12

"""Base exception for all TatSu errors."""

13

14

class ParseException(TatSuException):

15

"""

16

Base parsing exception with position information.

17

18

Attributes:

19

- message: str, error description

20

- line: int, line number where error occurred

21

- col: int, column number where error occurred

22

- pos: int, character position in input

23

- context: parsing context information

24

"""

25

```

26

27

### Grammar Compilation Errors

28

29

Errors that occur during grammar parsing and compilation phase, before any input parsing begins.

30

31

```python { .api }

32

class GrammarError(ParseException):

33

"""

34

Grammar definition and compilation errors.

35

36

Raised when:

37

- Grammar has invalid EBNF syntax

38

- Rule definitions are malformed

39

- Semantic inconsistencies in grammar

40

- Circular dependencies in rules

41

"""

42

43

class SemanticError(ParseException):

44

"""

45

Semantic analysis and action errors.

46

47

Raised when:

48

- Semantic action methods are malformed

49

- Type inconsistencies in semantic processing

50

- Missing semantic actions for required rules

51

"""

52

53

class CodegenError(ParseException):

54

"""

55

Code generation errors.

56

57

Raised when:

58

- Generated code would be invalid Python

59

- Template processing fails

60

- Output file cannot be written

61

"""

62

63

class MissingSemanticFor(SemanticError):

64

"""

65

Missing semantic action for a specific rule.

66

67

Raised when semantic actions object doesn't provide

68

required method for a grammar rule.

69

"""

70

```

71

72

### Parse Failure Exceptions

73

74

Errors that occur during input text parsing, providing detailed position and context information.

75

76

```python { .api }

77

class FailedParse(ParseException):

78

"""

79

Base parse failure with position information.

80

81

All parse failures include:

82

- Exact position where parsing failed

83

- Expected vs actual content

84

- Rule context and call stack

85

- Recovery suggestions when possible

86

"""

87

88

class FailedToken(FailedParse):

89

"""

90

Expected token not found.

91

92

Raised when:

93

- Literal string token doesn't match input

94

- Case-sensitive token matching fails

95

- End of input reached when token expected

96

"""

97

98

class FailedPattern(FailedParse):

99

"""

100

Regular expression pattern match failed.

101

102

Raised when:

103

- Regex pattern doesn't match at current position

104

- Pattern matches empty string when non-empty expected

105

- Invalid regex in grammar definition

106

"""

107

108

class FailedKeyword(FailedParse):

109

"""

110

Keyword match failed.

111

112

Raised when:

113

- Keyword token doesn't match input

114

- Keyword conflicts with identifier

115

- Keyword followed by invalid character

116

"""

117

118

class FailedSemantics(FailedParse):

119

"""

120

Semantic action execution failed.

121

122

Raised when:

123

- Semantic action method raises exception

124

- Semantic action returns invalid result type

125

- Custom validation in semantic action fails

126

"""

127

128

class FailedKeywordSemantics(FailedSemantics):

129

"""

130

Keyword semantic action failed.

131

132

Specialized semantic failure for keyword processing,

133

often indicating grammar design issues.

134

"""

135

```

136

137

### Structural Parse Failures

138

139

Errors related to grammar structure and control flow during parsing.

140

141

```python { .api }

142

class FailedRef(FailedParse):

143

"""

144

Rule reference resolution failed.

145

146

Raised when:

147

- Referenced rule doesn't exist in grammar

148

- Circular rule dependency detected

149

- Rule invocation stack overflow

150

"""

151

152

class FailedChoice(FailedParse):

153

"""

154

No choice alternative matched.

155

156

Raised when:

157

- All alternatives in choice expression fail

158

- Ordered choice doesn't find valid alternative

159

- Priority conflicts in choices

160

"""

161

162

class FailedCut(FailedParse):

163

"""

164

Cut point failed, prevents backtracking.

165

166

Raised after cut point when:

167

- Parsing fails beyond commit point

168

- No backtracking possible to earlier alternatives

169

- Parse recovery not available

170

"""

171

172

class FailedLookahead(FailedParse):

173

"""

174

Lookahead assertion failed.

175

176

Raised when:

177

- Positive lookahead doesn't match expected pattern

178

- Negative lookahead matches forbidden pattern

179

- Lookahead assertion at end of input

180

"""

181

182

class FailedLeftRecursion(FailedParse):

183

"""

184

Left recursion handling issue.

185

186

Raised when:

187

- Left-recursive rule cannot be resolved

188

- Infinite recursion detected

189

- Left-recursion algorithm fails

190

"""

191

192

class FailedExpectingEndOfText(FailedParse):

193

"""

194

Expected end of input but found more text.

195

196

Raised when:

197

- Parse completes but input remains

198

- Start rule matches but doesn't consume all input

199

- Trailing whitespace or comments not handled

200

"""

201

```

202

203

### Special Control Exceptions

204

205

Internal control flow exceptions, typically not seen by end users.

206

207

```python { .api }

208

class OptionSucceeded(ParseException):

209

"""

210

Internal: option succeeded.

211

212

Used internally for optional element control flow.

213

Should not be raised to user code.

214

"""

215

216

class NoParseInfo(ParseException):

217

"""

218

Parse info not available.

219

220

Raised when:

221

- ParseInfo requested but not enabled

222

- Parse context doesn't contain position data

223

- Information not available for generated code

224

"""

225

```

226

227

## Error Handling Patterns

228

229

### Basic Exception Handling

230

231

```python

232

import tatsu

233

from tatsu.exceptions import ParseException, GrammarError

234

235

# Handle grammar compilation errors

236

try:

237

model = tatsu.compile("invalid grammar {")

238

except GrammarError as e:

239

print(f"Grammar error at line {e.line}: {e}")

240

# Fix grammar and retry

241

242

# Handle parse failures

243

try:

244

result = tatsu.parse("expr = number;", "not_a_number")

245

except ParseException as e:

246

print(f"Parse failed at position {e.pos} (line {e.line}, col {e.col}): {e}")

247

# Provide user feedback or attempt recovery

248

```

249

250

### Detailed Error Information

251

252

```python

253

from tatsu.exceptions import FailedParse

254

255

try:

256

result = model.parse(user_input)

257

except FailedParse as e:

258

# Detailed error reporting

259

error_info = {

260

'message': str(e),

261

'position': e.pos,

262

'line': e.line,

263

'column': e.col,

264

'expected': getattr(e, 'expected', None),

265

'found': getattr(e, 'found', None)

266

}

267

268

# Show error context

269

lines = user_input.split('\n')

270

if e.line <= len(lines):

271

error_line = lines[e.line - 1]

272

print(f"Error on line {e.line}: {error_line}")

273

print(f"{'':>{e.col-1}}^ {e}")

274

```

275

276

### Semantic Action Error Handling

277

278

```python

279

from tatsu.exceptions import FailedSemantics

280

from tatsu.semantics import ModelBuilderSemantics

281

282

class SafeSemantics(ModelBuilderSemantics):

283

def number(self, ast):

284

try:

285

return int(ast)

286

except ValueError as e:

287

# Convert to TatSu exception for consistent handling

288

raise FailedSemantics(f"Invalid number format: {ast}") from e

289

290

def division(self, ast):

291

left, _, right = ast

292

if right == 0:

293

raise FailedSemantics("Division by zero not allowed")

294

return left / right

295

296

try:

297

result = model.parse("10 / 0", semantics=SafeSemantics())

298

except FailedSemantics as e:

299

print(f"Semantic error: {e}")

300

```

301

302

### Production Error Handling

303

304

```python

305

import logging

306

from tatsu.exceptions import ParseException, GrammarError

307

308

def safe_parse(grammar, input_text, **kwargs):

309

"""Production-ready parsing with comprehensive error handling."""

310

try:

311

model = tatsu.compile(grammar)

312

return {'success': True, 'result': model.parse(input_text, **kwargs)}

313

314

except GrammarError as e:

315

logging.error(f"Grammar compilation failed: {e}")

316

return {

317

'success': False,

318

'error': 'Invalid grammar definition',

319

'details': str(e)

320

}

321

322

except ParseException as e:

323

logging.warning(f"Parse failed: {e}")

324

return {

325

'success': False,

326

'error': 'Parse failure',

327

'position': {

328

'line': e.line,

329

'column': e.col,

330

'offset': e.pos

331

},

332

'message': str(e)

333

}

334

335

except Exception as e:

336

logging.exception("Unexpected error during parsing")

337

return {

338

'success': False,

339

'error': 'Unexpected error',

340

'details': str(e)

341

}

342

343

# Usage

344

result = safe_parse(my_grammar, user_input)

345

if result['success']:

346

process_ast(result['result'])

347

else:

348

show_error_to_user(result['error'], result.get('position'))

349

```

350

351

### Error Recovery Strategies

352

353

```python

354

def parse_with_recovery(model, input_text, max_attempts=3):

355

"""Attempt parsing with simple error recovery."""

356

357

for attempt in range(max_attempts):

358

try:

359

return model.parse(input_text)

360

361

except FailedToken as e:

362

if attempt < max_attempts - 1:

363

# Try skipping problematic character

364

pos = e.pos

365

input_text = input_text[:pos] + input_text[pos+1:]

366

print(f"Attempt {attempt + 1}: Skipping character at position {pos}")

367

else:

368

raise

369

370

except FailedExpectingEndOfText as e:

371

# Input parsed successfully but has trailing content

372

return e.ast # Return partial parse if available

373

374

raise ParseException("Parse recovery failed after maximum attempts")

375

```