Dil derleyicilerinde kaynak kodun gramer yapısını doğrulamak için kullanılan Aşağıdan Yukarıya (Shift-Reduce) ve Yukarıdan Aşağıya (Recursive Descent) ayrıştırma teknikleridir.
Ayrıştırma (Parsing), doğrusal karakter dizilerini (token dizileri) gramer kurallarına göre analiz ederek bir soyut sözdizim ağacı (AST) oluşturma sürecidir.
Aşağıdan Yukarıya (Bottom-Up) ayrıştırmada en yaygın yaklaşım Kaydır-İndirge (Shift-Reduce) yöntemidir. Tokenlar yığına atılır (Shift), yığının tepesindeki grup bir gramer kuralıyla eşleştiğinde sol taraftaki sembole indirgenir (Reduce).
Yukarıdan Aşağıya (Top-Down) ayrıştırmada ise Recursive Descent (Özyinelemeli İniş) yöntemi popülerdir. Her gramer kuralı (Expression, Term, Factor vb.) bir fonksiyona karşılık gelir. Fonksiyonlar birbirini çağırarak en tepedeki başlangıç sembolünden yapraklara doğru ağacı inşa eder.
Aşağıdaki uygulamalar PDF kaynaklarındaki pseudo kod akışını modern veri yapılarıyla ifade eder. Kenar durumları görünür bırakıldığı için örnekler doğrudan test edilebilir.
1// Basit Recursive Descent Parser (Expression -> Term [+/- Term]*, Term -> Factor [*// Factor]*)2class ExpressionParser {3 private tokens: string[];4 private index: number = 0;56 constructor(expression: string) {7 this.tokens = expression.match(/\d+|[+*/()-]/g) ?? [];8 }910 private peek(): string | null {11 return this.index < this.tokens.length ? this.tokens[this.index] : null;12 }1314 private consume(expected?: string): string {15 const t = this.peek();16 if (expected && t !== expected) {17 throw new Error(`Beklenen token: ${expected}, Alınan: ${t}`);18 }19 this.index++;20 return t ?? '';21 }2223 parse(): number {24 const val = this.expression();25 if (this.index < this.tokens.length) {26 throw new Error(`Ayrıştırılmamış fazlalık tokenlar: ${this.tokens.slice(this.index).join(' ')}`);27 }28 return val;29 }3031 private expression(): number {32 let val = this.term();33 while (this.peek() === '+' || this.peek() === '-') {34 const op = this.consume();35 const right = this.term();36 val = op === '+' ? val + right : val - right;37 }38 return val;39 }4041 private term(): number {42 let val = this.factor();43 while (this.peek() === '*' || this.peek() === '/') {44 const op = this.consume();45 const right = this.factor();46 val = op === '*' ? val * right : val / right;47 }48 return val;49 }5051 private factor(): number {52 const t = this.peek();53 if (t === '(') {54 this.consume('(');55 const val = this.expression();56 this.consume(')');57 return val;58 }59 if (t && /\d+/.test(t)) {60 return Number(this.consume());61 }62 throw new Error(`Geçersiz token: ${t}`);63 }64}Modu ve aritmetik ifadeyi noktalı virgülle ayırın. Modlar: SR (Shift-Reduce bottom-up), RD (Recursive Descent top-down). Örnek: RD; (3 + 5) * 2
Modu ve aritmetik ifadeyi noktalı virgülle ayırın. Modlar: SR (Shift-Reduce bottom-up), RD (Recursive Descent top-down). Örnek: RD; (3 + 5) * 2
En İyi Durum: O(N) doğrusal zamanda
Ortalama Durum: O(N)
En Kötü Durum: O(N) backtrack içermeyen gramerlerde
O(N) yığın derinliği veya AST boyutu - Bu algoritmanın karmaşıklığı belirtilmemiş.
Derleyiciler ve Ayrıştırma (Compilers & Parsing) Algoritması ile benzer veya alternatif olarak değerlendirilebilecek diğer başlıklar: