Skip to main content

Crate gcode

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§

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

Structs§

Argumentalloc
One address letter and its value (e.g. X, Y, Z, F, S).
AstBuilderalloc
ProgramVisitor that builds an owned Program and collects Diagnostics.
Blockalloc
One line of g-code: optional N number, comments, G/M/T codes, and word addresses.
Commentalloc
Comment text, kind, and source span.
Diagnosticalloc
A single recoverable parse issue with a DiagnosticKind and source Span.
Diagnosticsalloc
Collection of Diagnostics produced by a parse.
GeneralCodealloc
G-code: motion, coordinate system, plane selection, etc.
MiscellaneousCodealloc
M-code: spindle, coolant, program control, etc.
Programalloc
Top-level parse result: a sequence of blocks.
ToolChangeCodealloc
T-code: tool selection.
WordAddressalloc
Modal bare address at block level (e.g. X5.0, S12000) without a G/M/T prefix.

Enums§

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

Functions§

parsealloc
Parse G-code source into a Program or return Diagnostics on error.