LR (0)과 SLR 구문 분석의 차이점은 무엇입니까?


82

나는 내 컴파일러 개념에 대해 작업하고 있지만 약간 혼란 스럽습니다 ... 인터넷 검색은 확실한 대답을 얻지 못했습니다.

SLR과 LR (0) 파서는 하나이며 동일합니까? 그렇지 않다면 차이점은 무엇입니까?

답변:


249

LR (0) 및 SLR (1) 파서 모두 상향식, 방향성, 예측 파서 입니다. 이것은

  • 파서는 입력 문장을 다시 시작 기호 ( 상향식 ) 로 줄이기 위해 생산을 역으로 적용하려고 시도합니다.
  • 파서는 왼쪽에서 오른쪽으로 입력을 스캔합니다 ( 방향 ).
  • 파서는 반드시 모든 입력 ( 예측 )을 보지 않고 적용 할 감소를 예측하려고합니다.

LR (0) 및 SLR (1)은 모두 시프트 / 리 듀스 파서입니다 . 즉, 입력 스트림의 토큰을 스택에 배치하고 각 지점 에서 토큰을 스택으로 푸시하거나 일부를 줄여 토큰을 이동 합니다. 스택 맨 위의 터미널 및 비 터미널 시퀀스를 일부 비 터미널 기호로 되돌립니다. 모든 문법은 shift / reduce 파서를 사용하여 상향식으로 파싱 할 수 있지만 해당 파서는 결정적 이지 않을 수 있습니다 . 즉, 구문 분석기는 시프트 또는 축소를 적용할지 여부를 "추측"해야 할 수 있으며 결국 잘못된 선택을했다고 인식하기 위해 역 추적해야 할 수 있습니다. 결정 론적 시프트 / 리 듀스 파서가 아무리 강력하더라도 모든 문법을 파싱 할 수는 없습니다.

결정 론적 시프트 / 리 듀스 파서를 사용하여 처리 할 수없는 문법을 구문 분석하면 시프트 / 리 듀스 충돌 또는 충돌 감소 / 감소가 발생 하여 파서가 취해야 할 조치를 말할 수없는 상태에 들어갈 수 있습니다. 시프트 / 리 듀스 충돌에서는 스택에 다른 심볼을 추가해야하는지 아니면 스택의 맨 위 심볼에서 약간의 감소를 수행해야하는지 알 수 없습니다. 감소 / 감소 충돌에서 파서는 스택의 최상위 기호를 터미널이 아닌 일부로 대체해야한다는 것을 알고 있지만 사용할 감소를 말할 수 없습니다.

이것이 긴 설명 인 경우 사과드립니다. LR (0)과 SLR (1) 구문 분석의 차이를 해결할 수 있으려면 이것이 필요합니다. LR (0) 파서는 어떤 조치를 취할지 (따라서 0) 결정하기 위해 미리보기 토큰을 사용하지 않는 시프트 / 축소 파서입니다. 이는 파서의 모든 구성에서 파서가 선택할 수있는 명확한 작업이 있어야 함을 의미합니다. 특정 기호를 이동하거나 특정 축소를 적용합니다. 두 개 이상의 선택 사항이 있으면 구문 분석기가 실패하고 문법이 LR (0)이 아니라고 말합니다.

두 가지 가능한 LR 충돌은 시프트 / 리 듀스와 리 듀스 / 리 듀스라는 것을 상기하십시오. 이 두 경우 모두 LR (0) 자동자가 수행 할 수있는 작업이 두 개 이상 있으며 어떤 작업을 사용해야하는지 알 수 없습니다. 충돌하는 작업 중 적어도 하나는 감소이므로 합리적인 공격 라인은 파서가 특정 감소를 수행 할 때 더 조심하도록하는 것입니다. 좀 더 구체적으로 말하면, 파서가 다음 입력 토큰을보고 이동하거나 축소해야하는지 여부를 결정할 수 있다고 가정 해 보겠습니다. 파서가 그렇게하는 것이 "합리적"일 때만 축소하도록 허용하면 ( "합리적"의 일부 정의에 대해), 자동 장치가 특정 위치에서 이동하거나 축소하도록 선택하여 충돌을 제거 할 수 있습니다. 특정 단계.

SLR (1) ( "Simplified LR (1)")에서 파서는 이동 또는 축소 여부를 결정할 때 하나의 예견 토큰을 볼 수 있습니다. 특히 파서가 A → w (비 터미널 A 및 문자열 w의 경우) 형식의 무언가를 줄이려고 할 때 다음 입력 토큰을 찾습니다. 해당 토큰이 일부 파생에서 비 터미널 A 뒤에 합법적으로 나타날 수있는 경우 파서는 감소합니다. 그렇지 않으면 그렇지 않습니다. 여기서 직관은 어떤 경우에는 축소를 시도하는 것이 말이되지 않는다는 것입니다. 왜냐하면 지금까지 본 토큰과 다가오는 토큰을 감안할 때 축소가 정확할 수있는 방법이 없기 때문입니다.

LR (0)과 SLR (1)의 유일한 차이점은 충돌이있을 때 취할 조치를 결정하는 데 도움이되는이 추가 기능입니다. 이 때문에 LR (0) 파서로 구문 분석 할 수있는 모든 문법은 SLR (1) 구문 분석기로 구문 분석 할 수 있습니다. 그러나 SLR (1) 파서는 LR (0)보다 많은 수의 문법을 구문 분석 할 수 있습니다.

그러나 실제로 SLR (1)은 여전히 ​​매우 약한 구문 분석 방법입니다. 보다 일반적으로 사용되는 LALR (1) ( "Lookahead LR (1)") 파서를 볼 수 있습니다. 그들은 LR (0) 파서에서 충돌을 해결하려고 노력하지만 충돌 해결에 사용하는 규칙은 SLR (1)에서 사용되는 규칙보다 훨씬 정확하며 결과적으로 훨씬 많은 문법이 LALR (1)입니다. SLR (1)보다. 좀 더 구체적으로 말하면 SLR (1) 파서는 문법 구조를 살펴보고 언제 이동하고 축소해야하는지에 대한 자세한 정보를 확인하여 충돌을 해결하려고합니다. LALR (1) 구문 분석기는 문법과 LR (0) 구문 분석기를 모두 살펴보고 전환시기와 축소시기에 대한보다 구체적인 정보를 얻습니다. LALR (1)은 LR (0) 파서의 구조를 볼 수 있기 때문에 특정 충돌이 잘못된 경우를보다 정확하게 식별 할 수 있습니다.yacc그리고 bison, 기본적으로 LALR (1) 파서를 생성한다.

역사적으로 LALR (1) 파서는 일반적으로 훨씬 더 강력한 LR (1) 파서에 의존하는 다른 방법을 통해 구성되었으므로 LALR (1)이 그렇게 설명하는 것을 자주 볼 수 있습니다. 이를 이해하려면 LR (1) 파서에 대해 이야기해야합니다. LR (0) 파서에서 파서는 프로덕션 중간에있을 수있는 위치를 추적하여 작동합니다. 생산이 끝났다는 사실을 알게되면 줄이려고 노력합니다. 그러나 파서는 한 프로덕션의 끝과 다른 프로덕션의 중간에 있는지 여부를 알 수 없어서 이동 / 감소 충돌로 이어 지거나 두 개의 다른 프로덕션 중 어느 쪽이 끝에 도달했는지 알 수 없습니다. 갈등 감소). LR (0)에서 이것은 즉시 충돌을 일으키고 파서가 실패합니다. SLR (1) 또는 LALR (1)에서

LR (1) 파서에서 파서는 작동시 추가 정보를 추적합니다. 파서가 사용하고 있다고 생각하는 프로덕션을 추적하는 것 외에도 해당 프로덕션이 완료된 후 나타날 수있는 가능한 토큰을 추적합니다. 파서는 결정을 내려야 할 때뿐만 아니라 각 단계에서이 정보를 추적하기 때문에 LR (1) 파서는 LR (0), SLR (1) 또는 지금까지 얘기 한 LALR (1) 파서. LR (1)은 매우 강력한 파싱 기술이며, 어떤 시프트 / 리 듀스 파서에 의해 결정적으로 파싱 될 수있는 모든 언어가 LR (1) 오토 마톤으로 파싱 될 수있는 문법이 있다는 것을 약간 까다로운 수학을 사용하여 보여줄 수 있습니다. (이것은 모든 문법이결정 론적으로 파싱 할 수있는 것은 LR (1); 이것은 결정 론적으로 파싱 될 수있는 언어에 LR (1) 문법이 있음을 의미합니다. 그러나이 기능에는 대가가 따르며 생성 된 LR (1) 파서는 작동하는 데 너무 많은 정보가 필요할 수 있으므로 실제로 사용할 수 없습니다. 예를 들어 실제 프로그래밍 언어에 대한 LR (1) 파서는 올바르게 작동하기 위해 수십에서 수백 메가 바이트의 추가 정보가 필요할 수 있습니다. 이러한 이유로 LR (1)은 일반적으로 실제로 사용되지 않으며 대신 LALR (1) 또는 SLR (1)과 같은 약한 파서가 사용됩니다.

최근에는 GLR (0) ( "일반화 된 LR (0)")이라는 새로운 구문 분석 알고리즘이 인기를 얻고 있습니다. LR (0) 파서에 나타나는 충돌을 해결하려고하는 대신 GLR (0) 파서는 가능한 모든 옵션을 병렬로 시도하여 작동합니다. 몇 가지 영리한 트릭을 사용하면 많은 문법에 대해 매우 효율적으로 실행할 수 있습니다. 또한 GLR (0)은 모든 k에 대해 LR (k) 파서로 구문 분석 할 수없는 문법을 포함 하여 모든 문맥 자유 문법을 구문 분석 할 수 있습니다. 다른 파서도이 작업을 수행 할 수 있지만 (예 : Earley 파서 또는 CYK 파서) 실제로 GLR (0)이 더 빠른 경향이 있습니다.

더 많은 것을 배우고 싶다면, 이번 여름에 저는 컴파일러 입문 과정을 가르쳤고 파싱 기술에 대해 이야기하는 데 2 ​​주도 채 걸리지 않았습니다. LR (0), SLR (1) 및 기타 강력한 구문 분석 기술에 대한보다 엄격한 소개를 받고 싶다면, 제 강의 슬라이드와 구문 분석에 대한 숙제를 즐길 수 있습니다. 모든 교육 자료는 여기 내 개인 사이트에서 사용할 수 있습니다 .

도움이 되었기를 바랍니다!


24
이것은 훌륭한 대답입니다. 매우 명확하고 교육적인 방식으로 질문에 정확하게 답합니다. 내가 만난 최고의 답변 중 하나입니다.
NealB 2011 년

2
@templatetypedef : L (AL) R (1)과 SLR (1)의 차이점에 대해 조금 설명해야한다고 생각합니다. 이것이 SLR (1)이 흥미로운 선택으로 존재하는 이유입니다. 하지만 +1.
Ira Baxter

@Ira Baxter- 방금 토론을 업데이트하여 LALR (1) 및 LR (1)에 대해 조금 더 이야기했습니다. 이 내용을 살펴보고 추가해야 할 것이 있으면 알려주세요.
templatetypedef

1
@newbie LR (0) 파서에는 ACTION 테이블이 있지만 작업은 상태와 다음 토큰이 아닌 상태에 전적으로 의존합니다.
templatetypedef

1
@newbie 위에서 준 항목은 축소 항목입니다. 이 상태에 대한 ACTION 항목은 감소하는 것입니다.
templatetypedef

1

이것이 내가 배운 것입니다. 일반적으로 LR (0) 파서는 모호성을 가질 수 있습니다. 즉, 테이블의 한 상자 (파서를 생성하기 위해 파생)가 여러 값 (또는)을 가질 수 있습니다. 따라서 이러한 모호성을 제거하기 위해 SLR 파서가 생성됩니다. 그것을 구성하기 위해 goto 상태로 이어지는 모든 프로덕션을 찾고 왼쪽에서 프로덕션 기호에 대한 팔로우를 찾고 다음에있는 goto 상태 만 포함합니다. 이것은 원래 문법을 사용하여 불가능한 프로덕션을 포함하지 않는다는 것을 의미합니다 (상태가 다음 세트에 없음)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.