| Crates.io | runmat-parser |
| lib.rs | runmat-parser |
| version | 0.2.8 |
| created_at | 2025-10-15 03:38:53.998934+00 |
| updated_at | 2025-12-22 21:35:43.603019+00 |
| description | Parser for RunMat (MATLAB/Octave) producing HIR from token streams |
| homepage | https://runmat.org |
| repository | https://github.com/runmat-org/runmat |
| max_upload_size | |
| id | 1883622 |
| size | 132,677 |
This crate parses MATLAB/Octave source text into a structured AST used by HIR, the interpreter, and the JIT. It consumes tokens from runmat-lexer and implements a precedence-based expression parser plus statement/control-flow, functions, indexing, and object-oriented constructs. The parser aims to accept full MATLAB language syntax with accurate surface grammar while deferring semantic enforcement (e.g., name resolution, access checks, end arithmetic) to later phases.
Expressions (Expr):
end sentinel+, -, transpose ', non-conjugate transpose .', logical not ~&&, ||, &, |), ranges a:b[:c][ ... ], cell literals { ... }A(...), A[...], A{...}obj.field, obj.method(args...)@(x,y) expr, function handles @name?Qualified.Name (see Postfix section for chaining semantics)Statements (Stmt):
[a,b]=f())if/elseif/else/end, for/end, while/end, switch/case/otherwise/end, try/catch/endfunction ... end, global, persistentclassdef Name [< Super] ... end with properties, methods, events, enumeration, arguments blocksimport pkg.* and import pkg.sub.ClassPrecedence order (high → low):
(), [], {}, member ./method, transpose '/.')^/.^ (right-associative)+ - ~* / \ .*/./.\+ - (also handles tokenized .+ .- as . + +/-)== ~= < <= > >=& |&& ||a:b[:c] (binds after comparisons and logical ops inside endpoints)end can be used as an expression sentinel (e.g., A(5:end)), represented as Expr::EndKeyword. In command-form, a bare end token is accepted as a literal argument and surfaced as Expr::Ident("end") for compatibility.
Parentheses after identifiers are parsed as function calls when the callee is a bare identifier; otherwise as indexing (to support obj.method()(...) chaining, and array indexing on expressions).
Dotted access supports both member reads and method invocation; dynamic member s.(expr) is parsed where syntactically valid.
Command/function duality at statement start: name arg1 arg2 is parsed as FuncCall(name, [args]) when unambiguous. See “Command-form hardening” below for disambiguation rules.
true/false as idents), strings (double-quoted string scalars) and char arrays (single-quoted)[], cell arrays {}varargin (inputs) and varargout (outputs) are supported with
language placement rules enforced: each may appear at most once and must be
the last parameter in its respective list[a, ~, c] = f(...)end in indexing, struct and method accessclassdef, properties, methods, events, enumeration, optional super < handleproperties(Access=private), methods(Static)Produces ParseError with message, position, found token, and expected token hints.
Tests live under crates/runmat-parser/tests/ and are organized by feature:
cells_and_indexing.rs, lvalue_assign.rs, operators_extended.rs, logical_precedence.rsfunctions_handles.rs, multi_assign.rs, multi_output.rscommand_syntax.rs, ambiguous_command_and_metaclass.rs, fuzz_command_dynamic.rs, fuzz_command_edges.rsclassdef.rs, classdef_minimal.rsimports_namespaces.rs?Class) and postfix?Qualified.Name parses to Expr::MetaClass("Qualified.Name").?Class.prop → Expr::Member(MetaClass("Class"), "prop"); ?Class.method(args...) → Expr::MethodCall(MetaClass("Class"), "method", [args]).?pkg.sub.Class.size → Member(MetaClass("pkg.sub.Class"), "size").?Class.size → Member(MetaClass("Class"), "size").Member(MetaClass(c), field) to LoadStaticProperty(c, field) and MethodCall(MetaClass(c), m, args) to CallStaticMethod(c, m, argc).runmat-runtime.The MATLAB language allows “command-form” calls at statement start (name arg1 arg2). We implement:
Ident, numeric, string, or end), and is not immediately followed by (, ., [, {, or a transpose token.A(1)=v, A{1}=v, s.f=v, s.(n)=v are captured as AssignLValue before considering command-form.foo b(1) are rejected with a targeted error; users should write foo(b(1)) or quote b(1).... is supported across command-form lines."he said ""hi""").end as an argument alongside quoted args and across ellipsis.s.(expr) appears in the argument run (before/after tokens, or across ellipsis).import pkg.* and import top.mid.Class statements.Class.* statics.s.(expr)end and punctuation).arguments ... end: names are accepted today; adding type/default/range validation hooks is planned in HIR/runtime.enumeration: explicit value forms are parsed structurally; richer validations (conflicts/range) can be added.Static+Dependent invalid, Constant+Dependent invalid; Abstract+Sealed invalid; access values) occurs in HIR.end arithmetic, slice semantics, and column-major broadcasting are performed by the compiler/VM and runtime..+/.- are handled by token lookahead (. then +/-)."" escapes; single-quoted char arrays handled lexically via contextual apostrophe logic (in the lexer) to disambiguate transpose.varargin/varargout, command/function duality, private functions, packages) are parsed syntactically as identifiers or standard constructs. Semantic resolution happens in HIR/type phases.