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::coreparser 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 cuttingis 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 thealloccrate, enablingparseand the heap-allocated AST (Program,Diagnostics, etc.).serde(enabled by default) — Enables serialisation and deserialisation of core and AST types viaserde.
§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§
- Argument
alloc - One address letter and its value (e.g. X, Y, Z, F, S).
- AstBuilder
alloc ProgramVisitorthat builds an ownedProgramand collectsDiagnostics.- Block
alloc - One line of g-code: optional N number, comments, G/M/T codes, and word addresses.
- Comment
alloc - Comment text, kind, and source span.
- Diagnostic
alloc - A single recoverable parse issue with a
DiagnosticKindand sourceSpan. - Diagnostics
alloc - Collection of
Diagnostics produced by a parse. - General
Code alloc - G-code: motion, coordinate system, plane selection, etc.
- Miscellaneous
Code alloc - M-code: spindle, coolant, program control, etc.
- Program
alloc - Top-level parse result: a sequence of blocks.
- Tool
Change Code alloc - T-code: tool selection.
- Word
Address alloc - Modal bare address at block level (e.g.
X5.0,S12000) without a G/M/T prefix.
Enums§
- Code
alloc - One G, M, or T command (variant plus optional arguments).
- Comment
Kind alloc - How the comment appears in source: semicolon (
;...) or parentheses ((...)). - Diagnostic
Kind alloc - Category of parse diagnostic emitted during recovery.
- Value
alloc - Argument value: a literal number or a variable reference (e.g.
#1).
Functions§
- parse
alloc - Parse G-code source into a
Programor returnDiagnosticson error.