Switch branches/tags
Nothing to show
Fetching contributors…
Cannot retrieve contributors at this time
177 lines (130 sloc) 5.25 KB

# 2.3 节的练习

### 2.3.1

#### 解答

```expr -> expr + term
| expr - term
| term
term -> term * factor
| term / factor
| factor
factor -> digit | (expr)```

```expr -> {print("+")} expr + term
| {print("-")} expr - term
| term
term -> {print("*")} term * factor
| {print("/")} term / factor
| factor
factor -> digit {print(digit)}
| (expr)```

### 2.3.2

#### 解答

```expr -> expr expr +
| expr expr -
| expr expr *
| expr expr /
| digit```

```expr -> expr {print("+")} expr +
| expr {print("-")} expr -
| {print("(")} expr {print(")*(")} expr {print(")")} *
| {print("(")} expr {print(")/(")} expr {print(")")} /
| digit {print(digit)}```

#### 疑问

E -> {print("(")} E {print(op)} E {print(")"}} op | digit {print(digit)}

### 2.3.3

#### 解答

`repeat(sign, times) // 将 sign 重复 times 次输出，如 repeat('a',2) = 'aa'`

```num -> thousand hundred ten digit
{ num.roman = thousand.roman || hundred.roman || ten.roman || digit.roman;
print(num.roman)}
thousand -> low {thousand.roman = repeat('M', low.v)}
hundred -> low {hundred.roman = repeat('C', low.v)}
| 4 {hundred.roman = 'CD'}
| high {hundred.roman = 'D' || repeat('X', high.v - 5)}
| 9 {hundred.roman = 'CM'}
ten -> low {ten.roman = repeat('X', low.v)}
| 4 {ten.roman = 'XL'}
| high {ten.roman = 'L' || repeat('X', high.v - 5)}
| 9 {ten.roman = 'XC'}
digit -> low {digit.roman = repeat('I', low.v)}
| 4 {digit.roman = 'IV'}
| high {digit.roman = 'V' || repeat('I', high.v - 5)}
| 9 {digit.roman = 'IX'}
low -> 0 {low.v = 0}
| 1 {low.v = 1}
| 2 {low.v = 2}
| 3 {low.v = 3}
high -> 5 {high.v = 5}
| 6 {high.v = 6}
| 7 {high.v = 7}
| 8 {high.v = 8}```

### 2.3.4

#### 解答

```romanNum -> thousand hundred ten digit
thousand -> M | MM | MMM | ε
hundred -> smallHundred | C D | D smallHundred | C M
smallHundred -> C | CC | CCC | ε
ten -> smallTen | X L | L smallTen | X C
smallTen -> X | XX | XXX  | ε
digit -> smallDigit | I V | V smallDigit | I X
smallDigit -> I | II | III | ε ```

```romanNum -> thousand hundred ten digit {romanNum.v = thousand.v || hundred.v || ten.v || digit.v; print(romanNun.v)}
thousand -> M {thousand.v = 1}
| MM {thousand.v = 2}
| MMM {thousand.v = 3}
| ε {thousand.v = 0}
hundred -> smallHundred {hundred.v = smallHundred.v}
| C D {hundred.v = smallHundred.v}
| D smallHundred {hundred.v = 5 + smallHundred.v}
| C M {hundred.v = 9}
smallHundred -> C {smallHundred.v = 1}
| CC {smallHundred.v = 2}
| CCC {smallHundred.v = 3}
| ε {hundred.v = 0}
ten -> smallTen {ten.v = smallTen.v}
| X L  {ten.v = 4}
| L smallTen  {ten.v = 5 + smallTen.v}
| X C  {ten.v = 9}
smallTen -> X {smallTen.v = 1}
| XX {smallTen.v = 2}
| XXX {smallTen.v = 3}
| ε {smallTen.v = 0}
digit -> smallDigit {digit.v = smallDigit.v}
| I V  {digit.v = 4}
| V smallDigit  {digit.v = 5 + smallDigit.v}
| I X  {digit.v = 9}
smallDigit -> I {smallDigit.v = 1}
| II {smallDigit.v = 2}
| III {smallDigit.v = 3}
| ε {smallDigit.v = 0}```

#### 疑问

```LowHundreds → ε { LowHundreds.val = 0; }
| C { LowHundreds.val = 100; }
| CC { LowHundreds.val = 200; }
| CCC { LowHundreds.val = 300; }```

```RomanNumeral → Thousands Hundreds Tens Ones
{ RomanNumeral.val = Thousands.val + Hundreds.val + Tens.val + Ones.val;
printf(“%d\n”, RomanNumeral.val;) }```

### 2.3.5

#### 解答

expr -> expr expr op | digit

expr -> {print(op)} expr expr op | digit {print(digit)}