ladybird/Userland
Daniel Bertalan 22195d965f DevTools: Add StateMachineGenerator utility
This program turns a description of a state machine that takes its input
byte-by-byte into C++ code. The state machine is described in a custom
format as specified below:

```
// Comments are started by two slashes, and cause the rest of the line
// to be ignored

@name ExampleStateMachine // sets the name of the generated class
@namespace Test           // sets the namespace (optional)
@begin Begin              // sets the state the parser will start in

// The rest of the file contains one or more states and an optional
// @anywhere directive. Each of these is a curly bracket delimited set
// of state transitions. State transitions contain a selector, the
// literal "=>" and a (new_state, action) tuple. Examples:
//     0x0a => (Begin, PrintLine)
//     [0x00..0x1f] => (_, Warn)      // '_' means no change
//     [0x41..0x5a] => (BeginWord, _) // '_' means no action

// Rules common to all states. These take precedence over rules in the
// specific states.
@anywhere {
    0x0a         => (Begin, PrintLine)
    [0x00..0x1f] => (_, Warn)
}

Begin {
    [0x41..0x5a] => (Word, _)
    [0x61..0x7a] => (Word, _)
    // For missing values, the transition (_, _) is implied
}

Word {
    // The entry action is run when we transition to this state from a
    // *different* state. @anywhere can't have this
    @entry IncreaseWordCount
    0x09 => (Begin, _)
    0x20 => (Begin, _)

    // The exit action is run before we transition to any *other* state
    // from here. @anywhere can't have this
    @exit EndOfWord
}
```

The generated code consists of a single class which takes a
`Function<Action, u8>` as a parameter in its constructor. This gets
called whenever an action is to be done. This is because some input
might not produce an action, but others might produce up to 3 (exit,
state transition, entry). The actions allow us to build a more
advanced parser over the simple state machine.

The sole public method, `void advance(u8)`, handles the input
byte-by-byte, managing the state changes and requesting the appropriate
Action from the handler.

Internally, the state transitions are resolved via a lookup table. This
is a bit wasteful for more complex state machines, therefore the
generator is designed to be easily extendable with a switch-based
resolver; only the private `lookup_state_transition` method needs to be
re-implemented.

My goal for this tool is to use it for implementing a standard-compliant
ANSI escape sequence parser for LibVT, as described on
<https://vt100.net/emu/dec_ansi_parser>
2021-05-16 11:50:56 +02:00
..
Applets Userland: Tighten a *lot* of pledges! :^) 2021-05-13 23:28:40 +02:00
Applications Debugger: Add basic backtrace support 2021-05-16 00:47:01 +01:00
Demos Userland: Tighten a *lot* of pledges! :^) 2021-05-13 23:28:40 +02:00
DevTools DevTools: Add StateMachineGenerator utility 2021-05-16 11:50:56 +02:00
DynamicLoader DynamicLoader: Remove math functionality in favor of -lgcc 2021-05-07 15:35:50 +02:00
Games GameOfLife: Spell about action app name as "Game Of Life" 2021-05-15 17:55:49 +01:00
Libraries AK+Kernel+LibELF: Remove the need for IteratorDecision::Continue 2021-05-16 10:36:52 +01:00
Services LibC: Do not include errno.h inside unistd.h 2021-05-14 22:24:02 +02:00
Shell Userland: Tighten a *lot* of pledges! :^) 2021-05-13 23:28:40 +02:00
Utilities AK+Kernel+LibELF: Remove the need for IteratorDecision::Continue 2021-05-16 10:36:52 +01:00
CMakeLists.txt Tests: Establish root Tests directory, move Userland/Tests there 2021-05-06 17:54:28 +02:00