CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyparsing

A Python parsing module providing an alternative approach to creating and executing simple grammars

Pending
Overview
Eval results
Files

exceptions.mddocs/

Exception Handling

Exception classes for parsing errors with detailed location information and error recovery mechanisms. PyParsing provides a comprehensive exception hierarchy that helps developers identify and handle parsing failures with precise error reporting.

Capabilities

Base Exception Classes

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

class ParseBaseException(Exception):
    """Base class for all pyparsing exceptions."""
    
    def __init__(self, 
                 pstr: str, 
                 loc: int = 0, 
                 msg: str = None, 
                 elem: ParserElement = None): ...
    
    @property
    def line(self) -> str:
        """Get the line of text where the exception occurred."""
    
    @property  
    def lineno(self) -> int:
        """Get the line number where the exception occurred."""
    
    @property
    def col(self) -> int:
        """Get the column number where the exception occurred."""
    
    def mark_input_line(self, markerString: str = ">!<") -> str:
        """Return the input line with error position marked."""
    
    def explain(self, depth: int = 16) -> str:
        """Return detailed explanation of parsing failure."""

Specific Exception Types

Specialized exception classes for different types of parsing failures.

class ParseException(ParseBaseException):
    """Exception raised for general parsing failures."""
    
    def __init__(self, 
                 pstr: str, 
                 loc: int = 0, 
                 msg: str = None, 
                 elem: ParserElement = None): ...

class ParseFatalException(ParseException):
    """Exception that stops backtracking and parser recovery."""
    
    def __init__(self, 
                 pstr: str, 
                 loc: int = 0, 
                 msg: str = None, 
                 elem: ParserElement = None): ...

class ParseSyntaxException(ParseFatalException):
    """Exception for syntax errors in parsing."""
    
    def __init__(self, 
                 pstr: str, 
                 loc: int = 0, 
                 msg: str = None, 
                 elem: ParserElement = None): ...

Grammar Definition Exceptions

Exceptions related to grammar definition and structure.

class RecursiveGrammarException(Exception):
    """Exception for improperly defined recursive grammars."""
    
    def __init__(self, parseElementList: list): ...

Exception Usage Patterns

Basic exception handling:

from pyparsing import Word, alphas, ParseException

parser = Word(alphas)

try:
    result = parser.parse_string("123")  # Will fail
except ParseException as pe:
    print(f"Parse failed at line {pe.lineno}, column {pe.col}")
    print(f"Error: {pe}")
    print(pe.mark_input_line())

Detailed error reporting:

def parse_with_detailed_errors(parser, text):
    try:
        return parser.parse_string(text, parse_all=True)
    except ParseBaseException as pe:
        print(f"Parsing failed:")
        print(f"  Location: Line {pe.lineno}, Column {pe.col}")
        print(f"  Message: {pe}")
        print(f"  Context: {pe.line}")
        print(f"  Marked: {pe.mark_input_line()}")
        print(f"  Explanation: {pe.explain()}")
        return None

Custom error messages:

# Add custom error messages to parser elements
number = Word(nums).set_name("number")
operator = oneOf("+ - * /").set_name("arithmetic operator")
expr = number + operator + number

try:
    result = expr.parse_string("5 % 3")  # Invalid operator
except ParseException as pe:
    print(f"Expected {number.name} or {operator.name}")

Fatal exceptions to prevent backtracking:

# Use ParseFatalException to stop parser recovery
def validate_positive(tokens):
    if int(tokens[0]) <= 0:
        raise ParseFatalException("Number must be positive")

positive_int = Word(nums).set_parse_action(validate_positive)

Exception propagation in complex grammars:

# Control exception behavior in nested expressions
expr = Forward()
term = Word(nums) | "(" + expr + ")"
expr <<= term + ZeroOrMore(("+" | "-") + term)

# ParseFatalException will bubble up through the Forward reference
def check_balanced_parens(s, loc, tokens):
    if tokens.count("(") != tokens.count(")"):
        raise ParseFatalException("Unbalanced parentheses")

expr.set_parse_action(check_balanced_parens)

Error recovery strategies:

def parse_with_recovery(parser, text):
    """Parse with multiple recovery strategies."""
    try:
        # Try strict parsing first
        return parser.parse_string(text, parse_all=True)
    except ParseFatalException:
        # Fatal error - don't attempt recovery
        raise
    except ParseException as first_error:
        try:
            # Try partial parsing
            return parser.parse_string(text, parse_all=False)
        except ParseException:
            # Return original error with more context
            raise first_error

Custom exception classes:

class ConfigurationError(ParseException):
    """Custom exception for configuration parsing errors."""
    
    def __init__(self, pstr, loc, msg, elem=None):
        super().__init__(pstr, loc, f"Configuration error: {msg}", elem)

def validate_config_value(tokens):
    value = tokens[0]
    if not value:
        raise ConfigurationError("", 0, "Empty configuration value not allowed")
    return value

config_parser = Word(alphanums).set_parse_action(validate_config_value)

Exception Properties and Methods

Accessing exception information:

try:
    parser.parse_string(invalid_input)
except ParseException as pe:
    # Location information
    line_num = pe.lineno      # 1-based line number
    col_num = pe.col          # 1-based column number  
    line_text = pe.line       # Text of the line containing error
    
    # Error context
    marked_line = pe.mark_input_line("<<<ERROR>>>")
    explanation = pe.explain(depth=10)
    
    # Exception details
    error_msg = str(pe)       # Human-readable error message
    location = pe.loc         # 0-based character position

Exception chaining for complex parsers:

def create_detailed_parser():
    """Create parser with comprehensive error reporting."""
    
    # Add meaningful names to all elements for better error messages
    identifier = Word(alphas + "_", alphanums + "_").set_name("identifier")
    number = Word(nums).set_name("number")
    string_literal = QuotedString('"').set_name("string literal")
    
    value = (string_literal | number | identifier).set_name("value")
    assignment = (identifier + "=" + value).set_name("assignment")
    
    return OneOrMore(assignment).set_name("configuration")

# Usage with detailed error reporting
parser = create_detailed_parser()
try:
    result = parser.parse_string(config_text)
except ParseException as pe:
    print(f"Configuration parsing failed:")
    print(f"Expected: {pe.expected}")  # Available in some contexts
    print(f"Found: '{pe.line[pe.col-1:pe.col+10]}'")
    print(pe.explain())

Install with Tessl CLI

npx tessl i tessl/pypi-pyparsing

docs

common-expressions.md

core-elements.md

enhancement.md

exceptions.md

helpers.md

index.md

testing-debugging.md

tile.json