Rust Scopes List Notation Parser
This is a configurable parser for Scopes List Notation (SLN), written in Rust.
SLN was invented for the Scopes programming language, so also take a look at it.
It parses input using the token parser, which is an intermediate representation for code structure. In short, every value is either a symbol (represented as a string) or a parser (parsing other tokens).
Representation
SLN is a simple representation suitable for both code and data. It is indentation-based (similar to Python) and directly maps to a list representation (like Lisp). It also supports brackets for nesting, which is most useful for single-line expressions. You can use brackets to opt out of indentation entirely, treating SLN as a pure s-expression parser, or mix both styles.
Benefits
This notation offers several advantages:
- Simplicity and Flexibility: It can replace common text formats like XML, JSON, TOML, YAML...
- Multiline Strings: Ideal for embedding long texts (like HTML) or code from other languages (like shader code).
- Token Parser Integration: Parsed output is compatible with the token parser crate. You can reuse parsers or write your own without rewriting core logic.
- Prototyping for Languages: For DSLs or new languages, start with SLN and switch representations later without major refactors.
Usage
First, create a parser. Use the default Parser::new() for minimal features or Parser::scopes() for full SLN support (matching the Scopes language syntax). Then, parse any iterable of characters (from a string or file content) into a token parser.
Here's a basic example:
use fs;
use ;
Strings are parsed into lists. If prefixed (configurable), they become a list with a prefix symbol (like "string") followed by the content symbol. Otherwise, it's a single content symbol.
For full details, see the API documentation.
Configuration
The parser is highly configurable via builder methods. Key options include:
- Indentation: Set the number of spaces for one nesting level with
indent(u8). Set to 0 to disable indentation-based nesting. - Unpack Single Elements: Use
unpack_single(bool)to interpret lines with a single element as lists (or not). - Multi-Indent: Allow multiple indent levels per line with
allow_multi_indent(bool). - Brackets: Add bracket pairs with
with_brackets(left: char, right: char, prefix: Option<&str>)or disable withwithout_brackets(). - Strings: Add delimiters with
with_strings(delimiter: char, prefix: Option<&str>)or disable withwithout_strings(). - Comments: Add comment starters with
with_comments(char)or disable withwithout_comments(). - Separators: Add inline list separators with
with_separator(char)or disable withwithout_separator(). - Symbol Characters: Add always-single-char symbols with
with_symbol_character(char)or disable withwithout_symbol_character().
Example configuration:
let custom_parser = new
.indent // 2 spaces per level
.unpack_single
.with_brackets
.with_strings // Single-quoted strings without prefix
.with_comments; // Semicolon comments