Files
mist-website/content/docs/internals/parsing.mdx
T
2026-07-03 10:23:45 +02:00

77 lines
2.3 KiB
Plaintext

---
title: Parsing
description: PEG grammar structure, AST design, and how Mist source code is parsed.
icon: FileCode
---
The parser is built with [pest](https://pest.rs), a PEG parser generator. Grammar rules are defined in `grammar.pest` (693 rules).
### Key files
- `grammar.pest` — PEG grammar defining the entire language syntax
- `src/parser/common/` — Parse rule → AST conversions for expressions, statements, types, declarations
- `src/parser/items/` — Parse rule → AST conversions for top-level items (structs, enums, classes, functions, traits, impls, attributes)
- `src/ast/` — AST node types (expr.rs, statement.rs, top_level.rs)
- `src/error.rs` — Error types (PreAst parsing errors, Ast generation errors)
### Parsing entry points
```rust
// Parse a complete program
pub fn parse<'a>(source: &'a str) -> Result<Program, ParseError<'a>>
// Parse only the module declaration
pub fn parse_module<'a>(source: &'a str) -> Result<Option<(Visibility, Identifier)>, ParseError<'a>>
```
### Grammar Structure
The grammar follows a layered approach:
1. **Lexical rules** (silent) — `WHITESPACE`, `COMMENT`, `identifier`, `integer`, `float`, `string_lit`
2. **Primary expressions** — literals, paths, tuples, arrays, closures, control flow
3. **Term** — prefix operators + primary + postfix operators
4. **Expression** — terms joined by binary operators (via Pratt parser)
5. **Statements** — variable declarations, control flow (`if`, `while`, `for`, `match`, `loop`), blocks
6. **Top-level items** — functions, structs, enums, classes, traits, impls, type aliases, imports, module declarations, constants
### AST Structure
The AST preserves source positions via `Spanned<T>`:
```rust
pub struct Spanned<T> {
pub line: usize,
pub column: usize,
pub item: T,
}
```
Top-level items are wrapped as:
```rust
pub struct TopLevel(pub Spanned<TopLevelKind>, pub Vec<Attribute>);
```
Expressions use a fix-point representation for prefix/postfix operators:
```rust
Expression::Fix {
initial: Box<Expression>,
prefixes: Vec<Prefix>,
postfixes: Vec<Postfix>,
}
```
Binary expressions use Pratt parsing for correct precedence:
```rust
Expression::Binary {
lhs: Box<Expression>,
op: String,
rhs: Box<Expression>,
}
```
All operators are left-associative with a single precedence level.