Skip to content

Commit 84ce2c5

Browse files
committed
以 while 剖析重複規則
1 parent 82c0701 commit 84ce2c5

1 file changed

Lines changed: 35 additions & 2 deletions

File tree

book/零.一版/剖析(語法分析).md

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ fn 剖析變數宣告(&self, 游標: usize) -> Option<(O變數宣告, usize)>
363363

364364
語法展開也不外乎這兩個結構,一個在語法規則裡用 `|` 來表示「或」,用 `` 來表示「且」。
365365

366-
最後來看個「或」、「且」結構都用上的語法規則`原子式`,其實作不外乎這兩種結構的組合。
366+
來看個「或」、「且」結構都用上的語法規則`原子式`,其實作不外乎這兩種結構的組合。
367367

368368
```rust
369369
// 原子式 = 數字
@@ -393,7 +393,40 @@ fn 剖析原子式(&self, 游標: usize) -> Option<(O算式, usize)> {
393393
}
394394
```
395395

396-
其他規則基本按照這兩結構依樣畫葫蘆就行,但`重複原子式``重複乘除式`要處理一下左結合的問題。
396+
其他規則基本按照這兩結構依樣畫葫蘆就行,但`重複原子式``重複乘除式`需要額外處理左結合的問題,用遞迴來寫比較冗長麻煩(尤其 Rust 還要處理所有權),但其實形如:
397+
398+
```
399+
算式 = 乘除式・重複乘除式
400+
401+
重複乘除式 = +・重複乘除式
402+
| −・重複乘除式
403+
| e
404+
```
405+
用如下形式表示更加簡單,期中的 (x)* 表示 x 可重複零或多次:
406+
```
407+
算式 = 乘除式・(+・重複乘除式)*
408+
| 乘除式・(−・重複乘除式)*
409+
410+
```
411+
412+
在實作中用一個 `while` 迴圈就能輕鬆實作:
413+
414+
```rust
415+
fn 剖析算式(&self, 游標: usize) -> Option<(O算式, usize)> {
416+
let (mut 算式, mut 游標) = self.剖析乘除式(游標)?;
417+
while let Some((運算子, 新游標)) = self.消耗加減(游標) {
418+
let (右算元, 新游標) = self.剖析乘除式(新游標)?;
419+
420+
算式 = O算式::二元運算(O二元運算 {
421+
: Box::new(算式),
422+
: Box::new(右算元),
423+
運算子,
424+
});
425+
游標 = 新游標
426+
}
427+
Some((算式, 游標))
428+
}
429+
```
397430

398431
音界咒的 9 條語法展開規則都寫成函式後,就可以調用
399432
```

0 commit comments

Comments
 (0)