:py:mod:`raesl.compile.machine_files.builder` ============================================= .. py:module:: raesl.compile.machine_files.builder .. autoapi-nested-parse:: Code to construct line matching state machines. The entry point to create a state machine is calling 'create' on a StateMachineBuilder instance. A state machine has locations and edges. One location in a machine may have an 'initial' option denoting it is the first location of the machine. Locations may also be accepting, denoting it is a proper end state. The accepting option takes a name, making it possible to distinguish which end location of the state machine was reached. Edges start at a location and end at a location. Edges have a token-name, and may only be chosen when the input has a token with the same name. An edge may also have a tag option. The tag-name represents what kind of relevant token it is. When an edge is taken with a tag-name, the token matching with the edge is appended to a list associated with the tag-name. In this way, it is possible to extract relevant information from the matched sentence afterwards. State machine execution assumes the machine is deterministic. From a location, each outgoing edge must have a different token-name. Note that a scanner may not map unique text to a token. The latter is resolved by sorting the edges from most specific token-name to least specific token-name. In general, writing code to build locations and edges is bulky and hard to understand. Instead a text format is defined to allow writing the state machines as text, and let the computer build the state machine from the description. The text format accepted by the builder is: state-machine ::= MACHINE-NAME ":" { loc-def | edge-def }+ loc-def ::= LOC-NAME [ "initial" ] [ "accept" "=" ACCEPT-name ] ";" edge-def ::= LOC-NAME "->" LOC-NAME "[" TOKEN-NAME "]" [ "tag" "=" TAG-NAME ] ";" Locations in 'loc-def' must not exist already. Missing locations in 'edge-def' are silently created. Token names are defined in parsing/scanner.py. Module Contents --------------- Classes ~~~~~~~ .. autoapisummary:: raesl.compile.machine_files.builder.StateMachineLexer raesl.compile.machine_files.builder.StateMachineParser raesl.compile.machine_files.builder.ProcessingStateMachine raesl.compile.machine_files.builder.StateMachineBuilder .. py:class:: StateMachineLexer Bases: :py:obj:`sly.Lexer` Lexer for tokenizing state machine descriptions. Note that SLY and pylint are known not to like each other. .. py:attribute:: tokens .. py:attribute:: ignore :value: ' \t' .. py:attribute:: ignore_comment :value: '\\#.*' .. py:attribute:: NAME :value: '[A-Za-z][A-Za-z0-9_]*' .. py:attribute:: SQ_OPEN :value: '\\[' .. py:attribute:: SQ_CLOSE :value: '\\]' .. py:attribute:: COMMA_TK :value: ',' .. py:attribute:: SEMICOL_TK :value: ';' .. py:attribute:: EQ_TK :value: '=' .. py:attribute:: COLON_TK :value: ':' .. py:attribute:: ARROW_TK :value: '->' .. py:method:: ignore_newline(t) .. py:class:: StateMachineParser Bases: :py:obj:`sly.Parser` .. py:attribute:: tokens .. py:method:: error(t) Default error handling function. This may be subclassed. .. py:method:: machine(p) .. py:method:: mlines(p) .. py:method:: mlines(p) .. py:method:: mlines(p) .. py:method:: loc_line(p) .. py:method:: loc_line(p) .. py:method:: loc_options(p) .. py:method:: loc_options(p) .. py:method:: loc_option(p) .. py:method:: loc_option(p) .. py:method:: edge_line(p) .. py:method:: edge_line(p) .. py:method:: edge_options(p) .. py:method:: edge_options(p) .. py:method:: edge_option(p) .. py:class:: ProcessingStateMachine(name: str, processing_func: Optional[raesl.compile.machine_files.typing.ProcessingFunc] = None) Bases: :py:obj:`raesl.compile.state_machine.StateMachine` Extended StateMachine that also holds a callback function to add extracted parsing information into the ast. :param name: Name of the state machine, also the name of the matched sequence. :param processing_func: If not None, function that inserts relevant information from the matched line into the ast that is constructed. .. py:class:: StateMachineBuilder Class for easily constructing a state machine from a textual description. .. attribute:: lexer Lexer to tokenize the input text. .. attribute:: parser Parser to interpret the tokens. .. attribute:: machine State machine to be built. .. attribute:: locs Temporary location map filled while building the state machine. .. py:method:: ensure_loc(name: str) -> raesl.compile.state_machine.Location Make sure a location with the provided name exists. If it doesn't, create it. :param name: Name of the location to ensure. :returns: The location with the provided name. .. py:method:: create_loc(name: str, opts: List[Union[Tuple[str], Tuple[str, str]]]) -> raesl.compile.state_machine.Location Create a new location. :param name: Name of the location to create. :param opts: Location options, list of ('initial',) and/or ('accept', str) . :returns: The created location. .. py:method:: create(machine_text: str, processing_func: Optional[raesl.compile.machine_files.typing.ProcessingFunc] = None) -> ProcessingStateMachine Create a state machine by interpreting the provided state machine text. :param machine_text: Description of the state machine as defined by StateMachineLexer and StateMachineParser. :param processing_func: Optional processing function to copy relevant information into the abstract syntax tree. :returns: The state machine that implements the description.