Skip to content

Batuminien/FSMLang

Repository files navigation

FSMLang

A domain-specific language for defining and executing finite state machines.

Requirements

  • Python 3.8 or higher
  • No external dependencies — standard library only

Project Structure

fsmlang/
├── main.py        # Entry point — run this
├── lexer.py       # Tokenizer
├── ast_nodes.py   # AST node definitions + printer
├── recursive_descent_parser.py      # Recursive descent parser
├── example_programs/      # Valid example programs
│   ├── program1_traffic.fsm
│   ├── program2_vending.fsm
│   └── program3_gameai.fsm
└── malformed_programs/     # Programs with intentional errors
    ├── malformed1_no_initial.fsm
    ├── malformed2_bad_arrow.fsm
    ├── malformed3_no_machine_kw.fsm
    ├── malformed4_unclosed_brace.fsm
    └── malformed5_invalid_token.fsm

Usage

# Parse a program and check for errors
python main.py <source_file>

# Parse and print the AST
python main.py <source_file> --dump-ast

# Show help
python main.py --help

Examples

# Parse the traffic light example
python main.py examples/program1_traffic.fsm

# Dump its AST
python main.py examples/program1_traffic.fsm --dump-ast

# See a parse error
python main.py malformed/malformed1_no_initial.fsm

Language Overview

FSMLang programs consist of global variable declarations, machine definitions, and run statements.

// Global variable — accessible by all machines
int threshold = 10

machine MyMachine {
    // Local variable — accessible only within this machine
    int counter = 0

    state Idle {
        on_enter: output "Entering Idle"
        on_step:  counter = counter + 1
        on_exit:  output "Leaving Idle"
    }
    state Active {
        on_enter: output "Now Active"
    }

    initial: Idle

    transition Idle -> Active if counter > threshold
}

// Run for a fixed number of steps
run MyMachine for 20 steps

// Or run until Ctrl+C
// run MyMachine forever

State hooks

Hook When it runs
on_enter Once, when the machine enters this state
on_step Every step while this state is active (optional)
on_exit Once, when the machine leaves this state

Transitions

Transitions fire when their guard expression evaluates to true. If no guard is given, the transition fires unconditionally on the next step.

transition StateA -> StateB if counter > 10
transition StateA -> StateB              // unconditional

Run modes

run MyMachine for 100 steps   // runs exactly 100 steps
run MyMachine forever          // runs until Ctrl+C

Types

Type Example
int int x = 0
float float rate = 0.5
bool bool active = true
string string label = "hello"

Operators

Category Operators
Arithmetic + - * /
Comparison == != < > <= >=
Logical and or not
Unary - (negation)

Error Messages

The lexer and parser produce informative error messages with line and column numbers.

[Lexer Error] Line 5, Col 12: Unexpected character '@'
[Parse Error] Line 8, Col 9: Machine 'A' has no 'initial' declaration
[Parse Error] Line 12, Col 20: Expected '->' but got '-'

About

A domain-specific language for defining and executing finite state machines.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages