저는 shift-reduce 구문 분석에 대해 배우려고합니다. 우리가 ANSI C Yacc grammar에서 영감을 작업의 순서를 시행 재귀 규칙을 사용하여 다음과 같은 문법을 가지고 가정 :Shift-reduce : 언제 줄이기를 멈 춥니 다?
S: A;
P
: NUMBER
| '(' S ')'
;
M
: P
| M '*' P
| M '/' P
;
A
: M
| A '+' M
| A '-' M
;
그리고 우리는 구문 분석을 교대-감소하여 1 + 2를 구문 분석합니다. 먼저 1이 숫자로 이동합니다. 제 질문은 P로, M으로, A로, 마지막으로 S로 줄입니까? 어디에서 멈출 지 어떻게 알 수 있습니까?
S로 줄이고 '+'시프트한다고 가정합니다. 우리는 지금 포함하는 스택 거라고 : 우리가 '2'시프트를하면
S '+'
을 감축 될 수 있습니다
S '+' NUMBER
S '+' P
S '+' M
S '+' A
S '+' S
이제 마지막 줄의 양쪽에, S가 될 수있다 P, M, A 또는 NUMBER를 포함 할 수 있으며 모든 조합이 텍스트의 올바른 표현이라는 의미에서 여전히 유효합니다. 파서는 그것을 어떻게 알 수 있습니까?
A '+' M
그래서 전체 표현식을 A로 줄이면 S? 즉, 다음 토큰을 이동하기 전에 줄이기를 중지하는 것을 어떻게 알 수 있습니까? 이것이 LR 파서 생성에있어 핵심적인 어려움입니까?
편집 : 질문에 추가가 다음.
이제 1+2*3
을 구문 분석한다고 가정합니다. 일부 시프트/축소 작업은 다음과 같습니다.
Stack | Input | Operation
---------+-------+----------------------------------------------
| 1+2*3 |
NUMBER | +2*3 | Shift
A | +2*3 | Reduce (looking ahead, we know to stop at A)
A+ | 2*3 | Shift
A+NUMBER | *3 | Shift (looking ahead, we know to stop at M)
A+M | *3 | Reduce (looking ahead, we know to stop at M)
정확합니까 (아직 완전히 파싱되지 않았습니다)? 더욱이, 1 심볼에 의한 미리보기는 또한 A+M
을 A
으로 줄이지 말라고 말하면, *3
을 읽은 후에 필연적 인 구문 오류가 발생하게됩니까?
'1 + 2'가 제공 한 문법에 대한 시프트/감소 충돌을 생성하지 않습니까? – mcabral
아니요. Bison은 불만없이이를 받아들입니다 (% token NUMBER \ n %% \ n ... \ n %%로 포장 한 후). –