Skip to content

config

Configuration dataclass

Represents the configured rules of the scanner.

Source code in src/lectes/config/models.py
@dataclass
class Configuration:
    """
    Represents the configured rules of the scanner.
    """

    rules: list[Rule]

    @classmethod
    def from_text(cls, text: str) -> Self:
        """
        Build a configuration from grammar text.

        The text has one rule per line: a name, whitespace, then the regex,
        which is the rest of the line. Blank lines and lines starting with `#`
        are ignored.

        ## Example

        ```python
        from lectes import Configuration

        config = Configuration.from_text(
            '''
            # arithmetic
            INT     [0-9]+
            PLUS    \\+
            WS      \\s+
            '''
        )
        ```

        Raises:
            GrammarError: if the text has any errors; every error found is
                listed in its `problems`.

        Warns:
            GrammarWarning: once per rule that is valid but probably not what
                was intended, such as one that can match the empty string.
        """
        grammar = parse(text)

        if grammar.errors:
            raise GrammarError(grammar.errors)

        for line, message in grammar.warnings:
            warnings.warn(GrammarWarning(line, message), stacklevel=2)

        return cls(
            [Rule(name=name, regex=Regex(pattern)) for name, pattern in grammar.rules]
        )

from_text(text) classmethod

Build a configuration from grammar text.

The text has one rule per line: a name, whitespace, then the regex, which is the rest of the line. Blank lines and lines starting with # are ignored.

Example
from lectes import Configuration

config = Configuration.from_text(
    '''
    # arithmetic
    INT     [0-9]+
    PLUS    \+
    WS      \s+
    '''
)

Raises:

Type Description
GrammarError

if the text has any errors; every error found is listed in its problems.

Warns:

Type Description
GrammarWarning

once per rule that is valid but probably not what was intended, such as one that can match the empty string.

Source code in src/lectes/config/models.py
@classmethod
def from_text(cls, text: str) -> Self:
    """
    Build a configuration from grammar text.

    The text has one rule per line: a name, whitespace, then the regex,
    which is the rest of the line. Blank lines and lines starting with `#`
    are ignored.

    ## Example

    ```python
    from lectes import Configuration

    config = Configuration.from_text(
        '''
        # arithmetic
        INT     [0-9]+
        PLUS    \\+
        WS      \\s+
        '''
    )
    ```

    Raises:
        GrammarError: if the text has any errors; every error found is
            listed in its `problems`.

    Warns:
        GrammarWarning: once per rule that is valid but probably not what
            was intended, such as one that can match the empty string.
    """
    grammar = parse(text)

    if grammar.errors:
        raise GrammarError(grammar.errors)

    for line, message in grammar.warnings:
        warnings.warn(GrammarWarning(line, message), stacklevel=2)

    return cls(
        [Rule(name=name, regex=Regex(pattern)) for name, pattern in grammar.rules]
    )

Rule dataclass

Represents a scanner configuration rule.

Is actually a proxy for a regular expression.

Example

from lectes import Regex

Rule(name="INT_LITERAL", regex=Regex("0|([-]?[1-9]+[0-9]*))
Source code in src/lectes/config/models.py
@dataclass(frozen=True)
class Rule:
    """
    Represents a scanner configuration rule.

    Is actually a proxy for a regular expression.

    ## Example

    ```python
    from lectes import Regex

    Rule(name="INT_LITERAL", regex=Regex("0|([-]?[1-9]+[0-9]*))
    ```
    """

    name: str
    regex: Regex

GrammarError

Bases: LectesError

The grammar text passed to Configuration.from_text is invalid.

Every error found is available as problems, a list of (line, message) pairs. line is 1-based, or None when the problem isn't tied to a line.

Source code in src/lectes/config/errors.py
class GrammarError(LectesError):
    """
    The grammar text passed to `Configuration.from_text` is invalid.

    Every error found is available as `problems`, a list of `(line, message)`
    pairs. `line` is 1-based, or None when the problem isn't tied to a line.
    """

    def __init__(self, problems: list[tuple[int | None, str]]) -> None:
        super().__init__(
            "\n".join(
                message if line is None else f"line {line}: {message}"
                for line, message in problems
            )
        )
        self.problems = problems

GrammarWarning

Bases: UserWarning

The grammar text passed to Configuration.from_text is valid but probably not what was intended.

The 1-based grammar line is available as line and the text as message.

Source code in src/lectes/config/errors.py
class GrammarWarning(UserWarning):
    """
    The grammar text passed to `Configuration.from_text` is valid but probably
    not what was intended.

    The 1-based grammar line is available as `line` and the text as `message`.
    """

    def __init__(self, line: int, message: str) -> None:
        super().__init__(message)
        self.line = line
        self.message = message