Files
2025-02-Compiler/notes/4.md
2025-09-25 10:58:48 +09:00

104 lines
2.6 KiB
Markdown

# Syntax Anlysis 2
## Bottom-Up Parsing
Bottom-up Parsing is more efficient than Top-down parsing.
it uses LR grammars: Left-recursive and right-most derivation.
Rely on **Shift-reduce Parsers**.
example:
```c
E -> T | T + E
T -> int | int * T | (E)
```
```c
// reduce
int * int + int | T -> int
int * T + int | T -> int * T
T + int | T -> int
T + T | E -> T
T + E | E -> T + E
E |
// view as reversed, it seems right-most derivation
```
### Shift-Reudce Parsing
```c
E -> T | T + E
T -> int | int * T | (E)
```
| Stack | Input | Applied Production |
| ----------- | ----------------- | --------------------- |
| | `int * int + int` | shift |
| `int` | `* int + int` | shift |
| `int *` | `int + int` | shift |
| `int * int` | `+ int` | reduce `T -> int` |
| `int * T` | `+ int` | reduce `T -> int * T` |
| `T` | `+ int` | shift |
| `T +` | `int` | shift |
| `T + int` | | reduce `T -> int` |
| `T + T` | | reduce `E -> T` |
| `T + E` | | reduce `E -> T + E` |
| `E` | | |
**Action Selection Problem**
Which action should we take?
when shift, when reduce, which production applied?
#### LR-Style Grammars
* LR(k): left-toright scanning, right most derivation and k symbol lookahead
* LR(0) Grammar
LR(0) indicates grammars that can determine actions without any lookahead: there are no reduce-reduce and shift-reduce conflicts when using **only the symbols in the stack**.
represent shift-reduce parsing using an **NFA**, whose states are production with separator '`.`' on RHS.
for eample, a production `T -> (E)` has four states: `T -> .(E)`, `T -> (.E)`, `T -> (E.)`, `T -> (E.)`.
before `.` means already in stack, next item means expecting item.
plus an additional dummy production `S' -> S$` for a start and end state.
there are two types of transitions between the stats
- shift transition
- $\epsilon$ transition:
example:
```
S -> (L) | id
L -> LS | L,S
```
```
S' -> S$
S -> (L) | id
L -> S | L,S
```
It can be represented as a NFA:
```python {cmd matplotlib}
import sys
import pymupdf
from PIL import Image
doc = pymupdf.open("../pdf/L4.pdf")
pix = doc[22].get_pixmap(dpi=500)
img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
plt.imshow(img)
plt.axis('off')
plt.tight_layout()
plt.show()
```
* LR(1) Grammar