Files
dexpr/docs/parser.md
T
2026-08-18 15:16:14 +03:00

120 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Parser Modülü
**Konum:** `src/parser/`
Parser, kaynak kodu AST'ye dönüştürür. PEG (Parsing Expression Grammar) tabanlıdır ve `peg` crate'ini kullanır.
---
## Giriş Noktaları
**Dosya:** `src/parser/mod.rs`
| Fonksiyon | Dönüş | Açıklama |
|-----------|-------|----------|
| `program(source)` | `Vec<Stmt>` | Tam programı parse eder |
| `program_with_spans(source)` | `Vec<(usize, Stmt)>` | Byte offset'leriyle birlikte parse eder |
### `offset_to_span(source, offset) -> Span`
Byte offset'ini 1-indexed satır ve sütuna dönüştürür. UTF-8 karakter sınırlarını doğru şekilde hesaplar.
---
## Gramer Kuralları
**Dosya:** `src/parser/grammar.rs`
### Deyim (Statement) Ayrıştırma
| Kural | Ürettiği | Sözdizimi |
|-------|----------|-----------|
| `statement()` | `Stmt` | Herhangi bir geçerli deyim |
| `assignment()` | `Stmt::Assignment` | `x = expr` veya `x += expr` |
| `property_assignment()` | `Stmt::PropertyAssignment` | `a.b.c = expr` |
| `expr_stmt()` | `Stmt::ExprStmt` | Bağımsız ifade |
| `if_stmt()` | `Stmt::If` | `if cond then ... [else ...] end` |
**Bileşik atamalar:** `+=`, `-=`, `*=`, `/=`, `%=` operatörleri desugar edilir:
- `x += e``x = x + e`
**Özellik ataması:** `identifier ("." identifier)+ "=" expression` kalıbı ile nesne özelliklerine atama yapılır (örn: `a.b.c = 42`).
**Else zincirleri:** `else if` yapısı desteklenir ve rekürsif olarak parse edilir.
### İfade (Expression) Ayrıştırma - Öncelik Sırası
En düşükten en yükseğe:
1. Fonksiyon çağrıları
2. Mantıksal OR (`||`) — soldan birleşimli
3. Mantıksal AND (`&&`) — soldan birleşimli (`a && b || c` = `(a && b) || c`)
4. Karşılaştırma (`==`, `!=`, `<`, `<=`, `>`, `>=`, `in`) — soldan birleşimli
5. Toplama/Çıkarma (`+`, `-`) — soldan birleşimli (`10 - 3 - 2` = `5`)
6. Çarpma/Bölme/Mod (`*`, `/`, `%`) — soldan birleşimli
7. Tekli operatörler (`-`, `!`) — `unary()` kuralı; postfix ve `**`'dan gevşek bağlanır: `!o.active` = `!(o.active)`, `-2 ** 2` = `-(2 ** 2)`, `- -1` geçerli
8. Üs alma (`**`) — sağdan birleşimli, üs kısmı `unary()` (`2 ** -1` geçerli)
9. Postfix (`.prop`, `.method()`), atomik ifadeler
`&&` ve `||` VM'de kısa devre (short-circuit) çalışır; sağ taraf sadece gerektiğinde değerlendirilir (bkz. compiler.md).
### Postfix Kuralı
`postfix()` kuralı, herhangi bir atom üzerinde `.property` (özellik erişimi) ve `.method(args)` (metod çağrısı) zincirlemesini sağlar. Atom parse edildikten sonra ardışık `.identifier` veya `.identifier(args)` kalıpları uygulanır:
- `obj.field``Expr::PropertyAccess(obj, "field")`
- `obj.method(args)``Expr::MethodCall(obj, "method", args)`
- `obj.a.b.method()` → zincirleme erişim ve çağrı
### Atomik İfadeler
`atom()` kuralı temel ifade birimlerini parse eder:
| Tür | Örnek | Ürettiği |
|-----|-------|----------|
| Tanımlayıcı | `myVar` | `Expr::Variable` |
| Sayı | `42`, `3.14` | `Expr::Value(Number)` |
| String | `"hello"`, `'world'` | `Expr::Value(String)` |
| Boolean | `true`, `false` | `Expr::Value(Boolean)` |
| Null | `null` | `Expr::Value(Null)` |
| Parantezli ifade | `(a + b)` | İç ifade |
| Tekli negatif | `-x` | `Expr::UnaryOp(Neg, x)` |
| Tekli NOT | `!flag` | `Expr::UnaryOp(Not, flag)` |
### Literal Ayrıştırma
- **Sayılar:** Ondalık kısım opsiyonel (`42`, `3.14`)
- **Stringler:** Çift veya tek tırnak, escape sequence destekli
- **Tanımlayıcılar:** Ayrılmış kelimelerle çakışmamalı
### Ayrılmış Kelimeler
`if`, `then`, `else`, `end`, `true`, `false`, `null`, `in`
### Boşluk ve Yorumlar
- Boşluklar: space, tab, newline
- Satır yorumu: `// ...`
- Blok yorumu: `/* ... */`
---
## Hata Yönetimi
Parser hataları `peg` crate'inden gelir ve beklenen token/kural bilgisi içerir. `program_with_spans()` kullanıldığında byte offset'leri `offset_to_span()` ile satır/sütun bilgisine dönüştürülebilir.
---
## Kullanım Örneği
```rust
use dexpr::parser;
let source = r#"
result = (3 + 4) * 2
log(result)
"#;
let ast = parser::program(source).expect("Parse error");
// ast: Vec<Stmt> - Assignment, ExprStmt
```