Crate gcode

Source
Expand description

A parser for g-code programs, with both a convenient AST API and a zero-allocation visitor-based core designed for embedded environments.

Some explicit design goals of this crate are:

  • embedded-friendly: users should be able to use this crate without requiring access to an operating system (e.g. #[no_std] environments or WebAssembly)
  • deterministic memory usage: the crate::core parser can operate without dynamic allocation
  • error-resistant: the parser attempts to recover from erroneous input, reporting diagnostics and continuing where possible
  • performance: parsing should be reasonably fast, guaranteeing O(n) time complexity with no backtracking

§Getting Started

With the alloc feature (enabled by default), use parse to parse g-code into a Program. If any parse errors are emitted, parse returns Err with the collected Diagnostics.

use gcode::{Code, Value};

let src = "G90 (absolute)\nG00 X50.0 Y-10";
let program = gcode::parse(src)?;

assert!(program.blocks.len() >= 1);

for block in &program.blocks {
    for code in &block.codes {
        if let Code::General(g) = code {
            for arg in &g.args {
                match (arg.letter, &arg.value) {
                    ('X', Value::Literal(x)) => assert_eq!(*x, 50.0),
                    ('Y', Value::Literal(y)) => assert_eq!(*y, -10.0),
                    _ => {}
                }
            }
        }
    }
}

Parse errors are reported as Diagnostics and collected in Diagnostics.

For more complex use cases, including zero-allocation or streaming parsing, refer to the core module.

§Document model

G-code is modelled as a sequence of blocks. A Program (from parse) is the root: it has blocks. Each Block corresponds roughly to one line of source and contains an optional line number (N), comments, G/M/T commands (Code with Arguments), and bare word addresses (Block::word_addresses—e.g. X10.5 without a preceding G/M/T).

For example, this source:

G1 X10.5 Y20.0 F1500
M3 S1000
; start cutting

is a document of three blocks: the first has one G-code (G1) with arguments X, Y, F; the second has one M-code (M3) with S; the third has a comment.

Unlike JSON or XML, g-code has no single universal grammar; controllers and dialects differ, and the meaning of a block often depends on machine state or dialect rules. This crate therefore models g-code at the syntactic level: the parser represents what was written, not what the machine would do. Higher-level interpretation (e.g. whether X/Y are coordinates for a move) is left to downstream code.

§Zero allocation

To avoid dynamic allocation, do not enable the alloc feature and do not use the parse function (which builds an AST). Implement ProgramVisitor, BlockVisitor, and CommandVisitor and pass your visitor to core::parse; the parser drives your visitor and does not allocate.

§Spans

Each element’s original location in the source is retained as a Span.

This supports:

  • Showing where a parsing or semantic error occurred
  • Highlighting the current command when stepping through a program
  • Reporting progress (e.g. line/column) to the user or machine

In the core API, visitor methods receive a Span (e.g. BlockVisitor::line_number and BlockVisitor::comment). AST types (with alloc) have a span field (e.g. Block::span, Comment::span, GeneralCode::span, Argument::span).

§Feature Flags

  • alloc (enabled by default) — Enables the alloc crate, enabling parse and the heap-allocated AST (Program, Diagnostics, etc.).
  • serde (enabled by default) — Enables serialisation and deserialisation of core and AST types via serde.

§Internal Features

The following features are not intended for public use.

  • unstable-doc-cfg — Enables rustdoc labels for items gated by features (for docs.rs - requires nightly).

Modules§

  • A zero-allocation, push-based parser for g-code.

Structs§

Enums§

  • One G, M, or T command (variant plus optional arguments).
  • How the comment appears in source: semicolon (;...) or parentheses ((...)).
  • Category of parse diagnostic emitted during recovery.
  • Argument value: a literal number or a variable reference (e.g. #1).

Functions§