logic-parser

Crates.iologic-parser
lib.rslogic-parser
version1.3.0
sourcesrc
created_at2023-10-02 17:28:21.81979
updated_at2023-10-05 05:43:38.689548
descriptionA simple lexer & parser for logical expressions that supports output as AST, JSON and SVG
homepagehttps://github.com/paoloose/discrete-mathematics/tree/main/assignments/week1/logic-parser
repositoryhttps://github.com/paoloose/discrete-mathematics/tree/main/assignments/week1/logic-parser
max_upload_size
id990208
size164,829
Paolo Flores (paoloose)

documentation

README

Logic syntax tree generator

Rust library for lexing, parsing and visualizing logical expressions.

The code has no relevant dependencies more than thiserror for improving the error handling and an optional serde feature for deserializing a syntax tree from a well-formed JSON input.

The parser currently process one-liner expressions with the following Backus-Naur form:

expr := term [(<-> | ->) expr]
term := prop [(|| | &&) term]
prop := [~] ("true" | "false" | name | LPAREN expr RPAREN)

The concept is very new for me so don't expect this syntax to comply the standard. 😁 The parser is currently working as expected, reporting meaningful syntax errors and parsing any complex expression.

Want to use this library for the Web? Web Assembly bindings were also written! Look at the (unpublished) logic-parser-wasm library.

Examples

let expression = "((p || q)) => (q && ~(r))";

let tokens: Vec<Token> = Lexer::new().tokenize(expression)?;
let ast: ASTNode = Parser::new(&tokens).parse()?;

ast.as_json()

JSON output:

{
    "type": "operator.implies",
    "left": {
        "type": "operator.or",
        "left": {
            "type": "identifier",
            "name": "p"
        },
        "right": {
            "type": "identifier",
            "name": "q"
        }
    },
    "right": {
        "type": "operator.and",
        "left": {
            "type": "identifier",
            "name": "q"
        },
        "right": {
            "type": "operator.not",
            "operand": {
                "type": "identifier",
                "name": "r"
            }
        }
    }
}

Rendered SVG tree:

let horizontal_separation = 20_f32;
let vertical_separation = 30_f32;
let radius = 15_f32;

// ((p || q)) => (q && ~(r))

let svg = render_to_svg(
    ast,
    horizontal_separation,
    vertical_separation,
    radius
);

svg.as_xml()

Resulting tree

Testing

Unit tests were written for all the relevant parts of the library.

cargo test

References

Commit count: 0

cargo fmt