코덱 아날로그 신호를 디지털 전송회선으로 전송하기 위해 디지털 형태로 변환시키고, 또한 디지털 형태를 원래의 아날로그 신호로 복구시켜는 장치
HDLC의 데이터 전송 모드
표준(정규) 응답모드(NRM)
․반이중 통신을 하는 포인트 투 포인트 또는 멀티 포인트 불균형 링크 구성에 사용
․종국은 주국의 허가(Poll)가 있을 때에만 송신
비동기 응답 모드(ARM)
․전이중 통신을 하는 포인트 투 포인트 불균형 링크 구성에 사용
․종국은 주국의 허가(Poll) 없이도 송신이 가능하지만, 링크 설정이나 오류 복구 등의 제어 기능은 주국만 함
비동기 균형(평형)모드(ABM)
․포인트 투 포인트 균형 링크에서 사용․혼합국끼리 허가없이 언제나 전송할 수 있도록 설정
디지털 정보의 변조방식
• 반송파에 의한 변조
① 주파수편이변조(FSK)
반송파로 사용하는 정현파의 주파수에 정보를 싣는 변조 방식, 1200BPS 이하의 저속도인 비동기식 변복조기에 사용된다. (저속의 다이얼업에 주로 사용)
② 진폭편이변조(ASK)
반송파로 사용하는 정현파의 진폭에 정보를 싣는 방식
③ 위상편이변조(PSK)
반송파로 사용하는 정현파의 위상에 정보를 싣는 방식이며 2,400BPS 이상의 중고속도인 동기식 변복조기에 사용
④ 진폭위상편이변조(QAM)
반송파로 사용하는 정현파의 진폭과 위상에 정보를 싣는 변조 방식, 9600BPS의 고속전송으로 변조방식중 가장 빠르다.
⑤ 군변조(GM)
다수의 신호를 동일한 회선에 전송하기 위해 한번 변조된 피변조파를 다시 주파수 분할, 위상분할, 시분할 등에 한 그룹으로 묶어서 한 번에 변조하는 방식이다.
• 펄스변조방식
신호파인 아날로그 신호를 펄스로 분할하여 불연속적인 파형으로 만들어 아날로그 신호를 디지털 신호로 변환하는 변조방식
① 펄스진폭변조(PAM)
아날로그 신호파의 진폭에 비례해 반송파인 펄스파의 진폭을 변환시키는 변조 방식
② 펄스폭변조(PWM)
아날로그 신호파의 진폭에 비례해 반송파인 펄스파의 폭을 변환시키는 변조방식
③ 펄스 위치 변조(PPM)
아날로그 신호파의 진폭에 비례해 반송파인 펄스파의 위치를 변환시키는 변조방식
※ PAM, PWM, PPM(아날로그 변조): 신호전송시 잡음이 많다.
④ 펄스부호변조(PCM: 디지털변조)
연속적으로 변화하는 아날로그 신호인 펄스로 바꾸어 전송하고 수신측에서는 원래의 아날로그 신호로 환원하는 방식
펄스의 크기나 모양으로 정보를 전송하지 않고 펄스의 존재유무로 정보를 전송하므로 잡음, 일그러짐에 강하고 고속전송이 가능하며, 다중화에 유리하다. 채널당 정보량이 많다.
그러나 점유 주파수 대역폭이 넓고, PCM 특유의 잡음이 발생하며 가격이 비싸다. 고주파에 있어 전송 손실 및 누화가 발생한다. 주파수 이득을 저하시킨다.
※ 변조과정
(표본화)→(압축)→(양자화)→(부호화)→(복호화)→(신장)→(분리)
표본화 : 대표값을 찾는 단계
압축 : 양자화하기 전에 작은 PAM은 크게, 큰 PAM은 압축시키는 것
양자화 : 읽어들인 대표치를 수량화하는 단계
부호화 : 실질적인 신호변환(A→D)단계(코딩)
복호화 : 원래의 신호로 복원하는 단계(디코딩)
신장 : 수신측에서 얻은 PAM신호를 원래의 PAM신호의 크기로 만드는 것이다.
핸드오프(Hand Off) 이동통신망에서 통화중인 이동국이 현재의 셀에서 벗어나 다른 셀로 진입하는 경우, 셀이 바뀌어도 중단없이 통화를 계속 할 수 있다.
V ITU-T 권고안 시리즈 중 전화망을 통한 데이터전송
DQDB (Distributed Queue Dual Bus)
DQDB[디큐디비]는 도시권통신망에 사용되는 IEEE 802.6 규격인 QPSX (queued packet synchronous exchange)의 제어접속에 사용되는 프로토콜이다. 이 구조는 회선교환과 패킷교환이 모두 가능하며, 데이터, 음성 및 비디오 등의 전송을 지원한다. DQDB는 일정한 길이의 셀 중계기술을 사용하므로, 네트웍 전송량이 불안정한 곳에 적합하다.
로더의 기능 Allocation(주기억장치할당), Linking(연결), Relocation(재배치), Loading(적재)
단항연산 NOT
프로그램에서 변수들이 갖는 속성이 완전히 결정되는 시간 바인딩시간(Binding Time)
연산기호가 오퍼랜드들의 다음에 오는 표기법 Postfix표기법
주기억 장치에서 가장 오랫동안 사용되지 않은 페이지를 교체할 페이지로 선책하는 교체 알고리즘 LRU
OPT (Optimal Replacement, 최적 교체)
․앞으로 가장 오랫동안 사용하지 않을 페이지를 교체하는 기법․각 페이지의 호출 순서와 참조 상황을 미리 예측해야 하므로 실현 가능성이 희박함
FIFO(First In First Out)
․각 페이지가 주기억장치에 적재될 때마다 그때의 시간을 기억시켜 가장 먼저 들어와서 가장 오래 있었던 페이지를 교체하는 기법․이해하기 쉽고, 프로그래밍 및 설계가 간단하며, 벨레이디의 모순(Belady's Anomaly) 현상이 발생함
LRU(Least Recently Used)
․최근에 가장 오랫동안 사용하지 않은 페이지를 교체하는 기법․각 페이지마다 계수기나 스택을 두어 현 시점에서 가장 오랫동안 사용하지 않은 즉, 가장 오래 전에 사용된 페이지를 교체함
LFU(Least Frequently Used)
․사용 빈도가 가장 적은 페이지를 교체하는 기법. 프로그램 실행 초기에 많이 사용된 페이지가 그 후로 사용되지 않을 경우에도 프레임을 계속 차지할 수 있음
NUR(Not UsedRecently)
․최근에 사용하지 않은 페이지를 교체하는 기법․최근의 사용 여부를 확인하기 위해서 각 페이지마다 참조 비트(Reference Bit)와 변형 비트(Modified Dit, Dirty Bit)가 사용됨
SCR(Second Chance Replacement)
가장 오랫동안 주기억장치에 있던 페이지 중 자주 사용되는 페이지의 교체를 방지하기 위한 것으로, FIFO 기법의 단점을 보완하는 기법
Parser(파서)
Parser(파서)란 컴파일러의 일부로서, 원시 프로그램의 명령문이나 온라인 명령문, HTML 문서 등에서 마크업 태그 등을 입력으로 받아들여서 컴파일러 등을 처리전에 구문을 해석할 수 있는 단위로 여러 부분으로 분할 해주는 역할을 한다. 즉, 컴파일러나 인터프리터에서 원시 프로그램을 읽어들여, 그 문장의 구조를 알아내는 구문분석 (parsing) 을 행하는 프로그램을 말합니다.
파서는 필요한 모든 입력이 제공되었는지를 점검하기도 한다.
구문분석 (parsing) 이란, 컴파일러나 인터프리터가 프로그램을 이해해 기계어로 번역하는 과정중의 한단계로, 각 문장의 문법적 구성·구문을 분석하는 과정입니다. 정확하게 이야기하면, 원시 프로그램의 토큰열 (token sequence) 을 받아들여 문법에 맞게 파스 트리 (parse tree) 로 구성하는 것을 말한다. 구문분석의 종류에는 다음과 같은 것들이 있다:
하향식 파싱 (top-down parsing)
상향식 파싱 (bottom-up parsing)
재귀 하강식 파싱 (recursive descendent parsing)
예측형 파싱 (predictive parsing)
픽쳐 파싱 (picture parsing)
연산자 우선순위 파싱 (operator)
참조
5. 상향식 파싱(Bottom-Up Parsing)
5.0 소개
일반적인 상향식 파싱 기법은 3장에서 소개되었다. 이 장에서는 몇 가지 상향식 파싱 알고리즘을 설명한다.
간략히 말하면, 파싱은 한 언어로 된 입력 스트링과 그 언어의 문법이 주어지면 파스 트리를 구성하는 것이다. 상향식 파서는 밑에서 위쪽으로, 즉, 단말 노드로부터 루트까지의 방향으로 파스 트리를 구성한다.
5.1 LR 문법
하향식 파싱을 위한 문법이 LL문법인 것과 마찬가지로, 상향식 파싱을 위한 문법은 LR 문법이다. 여기에서 L은 입력 스트링을 왼쪽에서 오른쪽으로 읽는다는 것을 나타내고, R은 우측 유도를 생성해낸다는 것을 의미한다.(Left to right scanning Right most derivation) 이때 실제 유도는 역순으로 구성된다.
5.1.1 LR(k) Grammars
3장에서 정의되었던 핸들(handle), 문장형태(sentential form), 우측 유도(right derivation) 등의 용어를 써서 LR(k) 문법을 정의하여 보자.
한 문법이 LR(k)라면, 다음 조건을 만족한다.
우측 유도에서 다음과 같은 문장형태가 있을 때,
αβω
여기에서 ω 와 α 가 빈 스트링으로 유도될 수 있고, ω(if non empty) 가 터미널 심볼들로만 이루어진다면, 핸들 β 는 ω의 좌측 k개 심볼들을 보고서 구분될 수 있다.
실제에서는 k = 1 로 문법을 기술하고, 이를 LR(1) 문법이라 한다. 대부분의 프로그래밍 언어들의 문법은 LR(1)문법이다. LR(0) 문법은 핸들 다음의 심볼을 보지 않고도 파싱할 수 있음을 나타내므로 잘 쓰이지 않으며, 대부분의 프로그래밍 언어의 문법을 LR(0)문법으로 기술하기가 어렵다.
예1) 다음 문법은 LR(0)이 아니다.
1. E → E + T
2. E → T
3. T → T * F
4. T → F
5. F → (E)
6. F → Id
문장형태 "E + T * Id"에서 미리보기(lookahead)가 없다면, 핸들을 E + T(즉, rule 1)로 결정할 수 밖에 없다. 따라서 문장형태는 E * Id로 축소된다. 여기에서 다음 핸들은 Id가 되어(즉, rule 6) 문장형태는 E * F로 되고, 다음 핸들은 F(rule 4)여서 문장형태는 E * T가 된다. 이어서 다음 핸들은 T (rule 2)이어서 문장형태는 E * E로 축소된다. 이때, 이 문장형태에서는 핸들을 발견할 수 없어서 이 문장 형태는 오류가 된다. 즉, 다음과 같은 과정을 밟는다.
E + T * Id 핸들 E + T
E * Id 핸들 Id
E * F 핸들 F
E * T 핸들 T
E * E 핸들 없음
따라서, 이 문법은 LR(1) 문법이다.
예2) 다음문법은 LR(0)이다.
S → a S a
| b S b
| c
한 문법이 LR(k)라는 것을 보이는 것은 그것이 LR(k)가 아니라는 것을 보이는 것보다 어려운 일이다.
L(S) = c, aca, bcb, abcba, aabbbcbbbaa ........ , 즉, c를 중앙에 가진 a 와 b의 대칭 스트링(symmetric string)의 언어이다. 이 언어의 어떤 문장형태에서도 지나간 심볼을 보지 않고 핸들을 찾고 축소하는 것이 가능하다.
LR(0)문법과 LR(1)문법 사이에는 한 가지 관심이 가는 문법이 있는데, 이것이 SLR(1) 문법이다. 여기에서 S는 간단함(Simple)을 뜻한다. 이 문법으로 많은 프로그래밍 언어들의 구성 요소들을 기술할 수 있다. 이들 문법들 사이의 차이는 우리가 파서를 구성할 때 파싱 테이블을 만드는 방법에 차이가 있다.
5.2 LR 파싱
LR 파서들은 효율적(빠름)이고 오류의 발견이 빠르다. LR 파서의 파싱테이블을 손으로 만들기는 매우 어렵지만, 오늘날에는 주어진 언어의 문법으로 LR 파싱 테이블을 구성해주는 도구들이 많다. 우리는 이들 파서 생성 도구들이 어떻게 동작하는지 알기 위해 LR 파싱 기법을 공부한다.
LL 파서와 마찬가지로, LR 파서도 두부분, 즉, 파싱 테이블과 드라이브 루틴으로 구성할 수 있다.
LR파싱 테이블의 구성하는 과정은 다음의 두 단계이다.
1) item set들로 구성되는 파싱 상태들을 구한다.
2) 구해진 파싱 상태로부터 테이블을 구성한다.
파싱 상태들을 구할 때 미리보기(lookahead)를 쓰지 않으면, LR(0) 파서를 구성한 것이며, 이것은 구성이 쉬우나 언어의 수용 범위가 작게 된다.
상태들을 구할 때 한 개의 미리보기( lookahead)를 쓰면, 이는 LR(1) 파서를 구성한 것이며, 이는 구성하기 어렵고 테이블의 크기가 너무 커지나 수용 언어의 범위가 크게 된다.
따라서, 절충형인 SLR(1)을 씀 -- 상태 구할 때는 lookahead를 쓰지 않고, 테이블을 구할 때만 lookahead 를 쓴다. SLR 파서는 대부분의 프로그래밍 언어를 수용할 수 있다.
LR 파싱의 개념을 익히기 위해서, 이장에서는 SLR(1) 파서를 설명한다. 파싱 테이블을 구성하는 알고리즘을 설명하기 전에, 파싱 테이블을 어떻게 사용하는지를 보인다. 파싱 알고리즘은 shift-reduce 파싱 알고리즘이다.
5.2.1 Shift-Reduce 파싱
LR파서는 Shift-Reduce라 부르는 파싱 형식을 사용한다. 이 방식은 이전에 파싱된 상황을 기록하고 있는 파싱 스택을 사용한다. 이 파서는 스택의 내용과 입력을 참고하여, 다음에 취해야 할 행동을 결정한다.
파싱 스택은 이미 만들어져 있다고 가정한다.
파싱 테이블 구조는 상태 X 문법 심볼의 이차원 테이블이다. 테이블은 두 부분으로 구성되는데, 행동(action) 부분과 GOTO부분이다. 행동 부분은 "shift-reduce"행동을 나타내는데, 상태들이 행을 구성하고, 터미날 심볼들이 열을 구성한다. GOTO부분의 열도 상태들로 구성되고, 행은 난터미널 심볼들로 구성된다.
LR 파싱 테이블:
상태
행동(action)
t1 t2 t3 ... tm $
GOTO
A1 A2 ... Ak
0
Error/Accept/Shift/Reduce
상태번호들
1
...
n
Shift-Reduce 파서의 4 가지 행동:
Error : 테이블에서 빈자리, 문법 오류를 말함.
Accept: 입력 스트링이 문법적으로 맞음. 파싱 종료 상태
Shift: S#가 가리키는 상태로 전이, 입력 심볼과 S#를 스택에 Push
Reduce: R#는 문법의 생성규칙 번호 임. 스택의 top은 이 생성규칙의 rhs를 가지고 있으므로 이를 pop하여 lhs로 대치함. 다음 상태는 GOTO 에서 가리키는 상태임.
다음과 같이 파싱 테이블이 이미 구성되어 있다고 간주하자. 파싱 테이블은 상태 수 X 문법 심볼 수의 크기로 구성된다.
상태
Action
GOTO
id
+
*
(
)
$
E
T
F
0
S5
S4
1
2
3
1
S6
Accept
2
R2
S7
R2
R2
3
R4
R4
R4
R4
4
S5
S4
8
2
3
5
R6
R6
R6
R6
6
S5
S4
9
3
7
S5
S4
10
8
S6
S11
9
R1
S7
R1
R1
10
R3
R3
R3
R3
11
R5
R5
R5
R5
위의 문법과 주어진 LR파싱 테이블을 가지고 다음의 입력 문장을 파싱해 보자
id * ( id + id )
다음은 파싱 과정을 보인다. 이어서 각 단계를 설명한다. 스택의 탑은 오른쪽이다.
스택(Stack)입력(Input)행동(Action)
(1) 0 id * ( id + id ) $ S5
(2) 0id5 * ( id + id ) $ R6
(3) 0F3 * ( id + id ) $ R4
(4) 0T2 * ( id + id ) $ S7
0T2*7 ( id + id ) $ S4
0T2*7(4 id + id ) $ S5
0T2*7(4id5 + id ) $ R6
0T2*7(4F3 + id ) $ R4
0T2*7(4T2 + id ) $ R2
0T2*7(4E8 + id ) $ S6
0T2*7(4E8+6 id ) $ S5
0T2*7(4E8+6id5 ) $ R6
0T2*7(4E8+6F3 ) $ R4
0T2*7(4E8+6T9 ) $ R1
0T2*7(4E8 ) $ S11
0T2*7(4E8)11 $ R5
0T2*7F10 $ R3
0T2 $ R2
0E1 $ Accept
과정 1
파싱은 스택에 상태 0를 넣고, 입력의 끝에는 $를 추가하여 시작한다.
스택 입력 스트링 행동
(1) 0 id * (id + id) $
파싱 알고리즘에 따라 테이블을 참조하면, 상태 0에서 입력 심볼 id는 행동 S5, 즉, 입력 심볼을 스택에 넣고 상태 5로 전이하라는 것이다.
과정 2
스택 입력 스트링 행동
(1) 0 id * (id + id) $ S5
(2) 0 id 5 * (id + id) $
이때, 테이블을 참조하면, 상태 5에서 입력 심볼 *는 행동 R5로 생성규칙 6번의 오른쪽이 축소할 핸들임을 말한다. 따라서, 스택에서 핸들에 해당하는 부분을 모두 지우게 되는데, 이 부분이 id 5이다. 따라서 스택에는 0만이 남는다. 생성 규칙 6의 왼쪽 부분(F)이 스택에 넣어지기 때문에, 테이블에서 상태 0과 F에 해당하는 GOTO부분을 참조하여야 한다. 이 엔트리는 3이므로 이것을 스택에 넣는다.
과정 3
스택 입력 스트링 행동
(1) 0 id * (id + id) $ S5
(2) 0 id 5 * (id + id) $ R6
(3) 0 F 3 * (id + id) $
이제, 스택의 탑은 상태 3이고, 현재 입력 심볼은 * 이므로, 테이블은 생성규칙 4번으로 축소하라는 행동 R4이다. 따라서 생성규칙 4번의 오른쪽은 스택의 탑 부분인 핸들이다. 알고리즘은 스택의 탑을 제거하고 생성규칙 4번의 왼쪽인 T를 넣고, 상태 0에서 T 일 때의 GOTO테이블에서 다음 상태인 상태 2를 얻어 스택에 넣는다.
이와 같은 방법으로 나머지 과정을 수행하고 나면, 우리는 마지막 과정인 과정 19에 다다른다.
과정 19
스택의 탑은 상태 1이고 입력 심볼은 $이다. 이때, 테이블은 행동 Accept를 표시하고 있으므로, 파싱은 완저히 성공적으로 끝나게 된다. R2부터 R6까지의 파싱 과정의 축소 행동을 역으로 따라가면, 우리는 파스 트리를 만들 수 있다.
파싱 과정 중, 우리는 항상 다음과 같은 스택과 입력 스트링의 상태를 유지했다.
StackInput
s0x1s1 ... xmsmaiai+1 .... $}
여기서 s는 상태를 표시하고, x는 터미널과 난터미널의 나열을 표시하며, a는 입력 심볼들이다. 이것은 스택의 탑이 지금까지의 파싱 과정에 대한 정보를 누적하고 있는 유한 상태 기계와 같이 보인다.
우리는 무엇을 하여야 하는지 알기 위해서 단지 스택의 탑과 입력 심볼을 보아야 한다.
5.2.2 SLR 테이블 만들기
우리는 문법의 생성규칙들로부터 각각의 상태가 아이템(item)들의 집합인 위와 같은 유한 상태 기계를 구성할 수 있다.
Items: 포지션 마크("·")가 있는 생성규칙, 즉 LR(0) Item
ex) E → E · + T
즉, 파싱 과정 중 E로부터 유도될 수 있는 스트링 중 E는 이미 확인했고, 앞으로 + T를 보려한다.
Item들을 모아서 Item set을 구성하고, 한 Item set이 한 상태가 된다.
알고리즘:
Constructing States
(0) 새 nonterminal S'를 만들어 S' → S인 새로운 생성규칙을 문법에 추가한다.
(1) S가 시작 심볼이면, S' → ·S를 시작상태 상태0에 추가한다.
(2) Closure: 상태에 A → x ·Xα가 있으면, 문법에 있는 모든 X → ω에 대하여 Item X → ·ω를 상태에 추가한다.
(3) 새로운 상태를 생성하기: 현재 상태에 있는 모든 A → x ·zω에 대하여 A → xz ·ω를 가지는 새 상태를 만든다. 새 상태는 서로 다른 모든 z에 대하여 만든다.
(4) 더 이상 새로운 상태가 만들어지지 않을 때까지 (2)와 (3)을 반복한다.
예4) 다음 문법의 상태들을 만들어 보자.
1. E → E + T
2. E → T
3. T → T * F
4. T → F
5. F → (E)
6. F → Id
Step 0
E' → E를 문법에 추가한다.
0. E' → E
1. E → E + T
2. E → T
3. T → T * F
4. T → F
5. F → (E)
6. F → Id
Step 1
State 0
E' → ·E
Step 2
Sttate 0의 Closure를 구하여 State 0에 추가한다.
State 0
E' → ·E
E → ·E + T
E → ·T
T → ·T * F
T → ·F
F → ·(E)
F → ·Id
Step 3
State 0에 대하여 알고리즘의 (3)을 적용하여 새로운 상태들을 만든다.
State 1
E' → E·
E → E ·+ T
State 2 State 3 State 4 State 5 State 6
E → T· T → F· F → (·E) F → Id· E → E +· T
T → T·* F E → ·E + T T → ·T * F
E → ·T T → ·F
T → ·T * F F → ·( E )
T → ·F F → ·Id
F → ·( E )
F → ·Id
State 7 State 8 State 9 State 10 State 11
T → T *·F F → ( E·) E → E + T· T → T * F· F → ( E )·
F → ·( E ) E → E·+ T T → T·* F
F → ·Id
SLR(1)테이블 구성
이 상태들을 이용하여 LR(0) 파싱테이블을 구성할 수 있다. 그러나 이 문법이 LR(0)문법이 아니기 때문에(예 1과 같이), 이들을 SLR Item으로 보고 lookahead를 동원하여 SLR(1)테이블을 구성한다.
알고리즘
Constructing of an SLR(1) Parsing Table
(1) Shift:
상태 m에 A → x·aω가 있고, 입력 a 에 대하여 상태 n에 A → xa·ω가 있으면, Table[m,a] = Sn 이다.
(2) Reduce:
상태 n에 A → ω·가 있으면 Table[n,a] = Ri이다. 이때 I 는 생성규칙 A → ω의 번호이고, a 는 FOLLOW(A)이다.
(3) Accept:
상태 n에 S' → S·가 있으면, Table[n,$] = Accept이다.
(4) GOTO's:
상태 m에 A → x·Bω가 있고, 상태 n에 A → xB·ω가 있으면, Table[m,B] = n 이다.
예5) 예4에서 구해진 상태들을 이용하여 SLR(1)파싱 테이블을 구성하자.
상태
Action
GOTO
id
+
*
(
)
$
E
T
F
0
S5
S4
1
2
3
1
2
3
4
5
6
7
S5
S4
10
8
9
R1
S7
R1
R1
10
11
5.2.3 Shift-Reduce 충돌
때때로, 파서는 한 생성규칙에 대하여 쉬프트를 계속할 것인지, 또는, 다른 생성규칙으로 축소할 것인지를 결정할 수 없는 때가 있다.
shift-reduce충돌은 한 상태에서 하나의 lookahead에 대하여 Shift해야 할지, 아니면, 스택의 핸들을 Reduce해야 할지 결정할 수 없는 상태로, 파싱테이블을 구성할 때 한 엔트리에 두 개 이상의 행동이 기록된다. 이것은 문법이 SLR(1)문법이 아님을 (혹은 LR(1)테이블이라면, LR(1)문법이 아님을)말하고 있다.
한 가지 해결책은 문법을 다시 기술하는 것이고, 다른 방법은 가능하다면, 상황을 분석하여 어느 행동이 적합한지를 결정하는 것이다.
대개의 경우, 축소되는 생성규칙과 입력 심볼의 순위를 비교하여, 생성규칙의 순위가 높으면 축소(reduce)를, 그렇지 않으면 쉬프트(shift)를 선택한다. 같은 우선순위의 경우는 결합법칙을 이용하여, 좌측 결합을 만족하면 축소(reduce)를, 우측 결합을 만족하면 쉬프트(shift)한다.
5.2.4 Reduce-Reduce충돌
때때로, 파서는 여러 개의 생성규칙에 대하여 축소하여야 하는 상황이 발생할 수 있다. 즉, reduce-reduce충돌은 스택의 핸들이 한 개 이상의 생성규칙에 대하여 축소(reduce)를 표시하는 경우이다. shift-reduce충돌 때와 마찬가지로, 문법이 SLR(1) 문법이 아니면, 테이블의 한 엔트리에 축소할 한 개 이상의 생성규칙이 표시된다.
이 경우의 충돌 해결은 축소되는 생성규칙들의 우선순위를 비교하여, 우선 순위가 높은 것을 선택한다.
5.2.5 LR파서의 종류
LR(0)파서
SLR(1)파서
LR(1)파서
LALR(1)파서
5.2.6 LR 파서 생성기
지금까지의 하향식 파싱 알고리즘을 논의한 결과로, 실제의 프로그래밍 언어를 위한 LR 파서를 손으로 만든다는 것은 매우 어려운 일임을 알게 되었을 것이다. 따라서, 수많은 프로그래머들이 LR 파서를 생성하는 파서 생성기들을 제작하였고, 우리는 이들을 선택하여 사용할 수 있게 되었다. 이들중 가장 유명한 것은 아마도 유닉스 운영체제에서 LALR(1) 파서를 생성하는 YACC(Yet Another Compiler Compiler)일 것이다.