"가장 가까운 일치"이외의 "dangling else"문제에 대한 다른 해결책이 있습니까?


9

다음 문맥 자유 문법 선물은 "다른 매달려"유형의 모호성 (상상 의미 와 의미 와 명령 또는 블록의 다른 종류의 약자) : 예를 들어, 는 또는 로 구문 분석 될 수 있습니다 이 문법에서 가장 단순하고 가장 짧은 모호한 단어입니다).aif expr thenbelsec

SaSbS|aS|c
aacbc(a(acbc))(a(ac)bc)

이 "dangling else"모호성을 해결하는 "표준"방법은 "else"( ) 문이 가장 가까운 / 가장 "if-then"( ) 과 쌍을 이루도록 합니다. 다음과 같이 수행 할 수 있습니다. 이 문법은 분명합니다. 위의 예에서는 구문 분석을 강제 실행합니다 .ba

SaTbS|aS|cTaTbT|c
(a(acbc))

질문 : 의 파싱을 강제 할 모호성을 해결하는 또 다른 자연적인 방법이 있습니까? 즉, 위의 두 언어와 동일한 언어를 생성하고 모호하지 를 로 구문 분석하는 문법을 찾고 있습니다 .(a(ac)bc)aacbcaacbc(a(ac)bc)

비고 : 첫 번째 시도는 다음과 같습니다. 는 필요에 따라 의 모호성을 해결 하지만이 문법은 여전히 ​​모호합니다. aacbacbc(a (ac) b (acbc)) 또는 (a (acb (ac)) bc ) .

SaSbS|aU|cUaU|c
aacbcaacbacbc(a(ac)b(acbc))(a(acb(ac))bc)

1
그리고 마지막 예에서, 가능한 두 구문 분석 중 "자연적"또는 올바른 것으로 간주하는 이유는 무엇입니까?
rici

@rici 예, 이것은 까다로운 질문입니다! 나는 구문 분석을 생성하는 모호하지 않은 문법에 입니다. 내가 주로 걱정하는 것은 즉 (더와 '초 이상 일치하는 S')가 번째 마지막 와 번째 (잎 안쪽 의 타의 추종을 불허). aacbacbcaaaaaacbcbcbcabkbkaa
Gro-Tsen

답변:


7

이 문제는 일부 닫는 괄호가 생략 된 표현식에서 괄호를 일치시키는 문제와 정확히 유사합니다. 여기에 "if"(또는a 대표적인 문법에서)는 열린 괄호와 "else"(b)는 가까운 괄호입니다. (의 순서에서a모래 b기계적으로 삽입 할 수 있습니다 c각각 앞에 하나를 배치하여 b 괄호 뇌에 더 잘 맞기 때문에 문제가있는 것처럼 씁니다.

기존의 "가장 근접한"댕글 링-해상도는 가장 근접한 가장 최근의 열림과 각각 일치합니다. 즉, 일치하는 열기와 일치하는 닫기 사이에 일치하지 않는 열기 (또는 해당 문제에 대한 닫기)가 없습니다.

가능한 대안 중 하나는 가장 근접한 가장 빠른 오픈과 각각의 클로저를 일치시키는 것입니다. 여기서 "가능한"은 괄호 중첩을 위반하지 않고 오픈을 일치시킬 수 있음을 의미합니다 (예 : 첫 번째(()() 마지막과 일치 할 수 없다 )).

이 일치는 외부에서 수행되어야하므로 모든 묶음 쌍이 일치 할 때까지 닫기에 대한 일치가 시도되지 않습니다. 이 사실은 구문 분석이 알고리즘을 사용하여 구문 분석을 생성하는 것을 불가능하게 만듭니다. 구문 분석은 문자열을 완전히 일치하는 세그먼트로 분할 한 후 (끝이 일치하는 범위를 효과적으로 제한하기 때문에) 양쪽 끝에서 안쪽으로 작동해야하기 때문입니다.

그러나 온라인 왼쪽에서 오른쪽 파서가 존재하지 않는다고해서 CFG가 명확하지 않다는 것을 의미하지는 않습니다. (아마도 : 회문 언어는 양쪽 끝에서 중간쪽으로 구문 분석해야하지만 명확한 문법을 ​​작성하는 것은 쉽습니다).

"가장 일치하는"괄호 문제에 대한 문법을 ​​만들기 위해 필자는 필적 할 수없는 오픈 뒤에는 일치하는 오픈이 올 수 없다는 사실에 의존했습니다. 일치하는 경우 일치하지 않는 열기가 일치하는 열기의 닫기와 일치 할 수 있기 때문에 가장 일치하는 속성이 적용되지 않으므로 일치하지 않는 것이 가장 일치하는 속성을 위반합니다.

여기 약간 어색한 문법이 있습니다 :

SU|MUT|aUbT|aUbc|aMbUMaMbM|cTaT|ac

S 시작 기호입니다. M 완전히 일치하는 진술입니다. U 확실히 일치하지 않는 진술입니다. a이므로 비워 둘 수 없습니다.) T 타의 추종을 불허하는 "꼬리" a에스. 일치하지 않는 개방형에 대한 위의 사실은 문법에서 직접 읽을 수 있습니다. 일치하지 않는 모든 개방형은T, ㅏ T 끝에 만 나타날 수 있습니다 U, 그리고 U 뒤에 만 올 수 있습니다 T.

어지러움은 예방에서 비롯됩니다 U빈 문자열과 일치하지 않습니다. 그것은 내가 모호한 모호성을 고려하는 것을 방지합니다. 개방과 닫힘의 일치가 모든 대체 파싱에서 동일하다는 점에서 가짜입니다. 만약Unull을 허용하면 완전히 균형 잡힌 문자열을 파생시킵니다. 이후S 사실상 MU, 그것은 당신이 완전히 균형 잡힌 것을 고려할 수있는 모호성을 초래합니다 S 일련의 M 뒤에 빈 U또는 하나 이하 M 완전히 균형 잡힌 U.

아마 내가 선택한 것보다 더 나은 해결 방법이있을 것입니다. 그러나 이것은 효과가있는 것으로 보이며 Bison의 GLR 파서와 잘 어울립니다. 그 파서는 모호성을 처리하기 위해 추가 코드를 작성하지 않는 한 모호한 구문 분석에 대해 불평하며 너무 게으르지 않습니다. 나는 최대 20 개의 open + closes 문자열로 테스트했으며 올바르게 중첩 된 모든 시퀀스에 대해 명확하게 중첩 된 시퀀스에 대한 구문 분석을 생성하지 않고 명확한 구문 분석을 생성 한 것으로 보입니다.


내가 결론을 내린 것을 축하 한 것은 아마도 불가능했을 것입니다! 나는 길이가 ≤16 인 단어의 경우이 문법이 실제로 모호하지 않으며 내 질문의 단어와 동일한 단어를 생성하는지 실험적으로 확인했습니다. 이제 어떻게 작동하는지 자세히 이해해야합니다!
Gro-Tsen

@ Gro-Tsen : 두 번째 단락이 설명에 도움이되기를 바랍니다. 문법은 다음과 같이 모호한 모호성을 남겨두고 훨씬 간단합니다.SaSbT|aMbS (M 내 솔루션에서와 같이 TaT|c) 그리고 그것이 문제에 대해 생각할 때 생각해 낸 것입니다. 스스로를 만들어야한다는 것을 확신시키는 데 시간이 걸렸습니다.U모호한 구문 분석을 피하기 위해 null이 불가능합니다 (모호성이 상대적 임에도 불구하고). 그리고 그것을 시행하기로 선택한 방식으로 내 불쾌감을 해결하는 데 더 오랜 시간이 걸립니다. 더 우아한 프리젠 테이션이있을 것입니다.
rici

0

a + b + c + d + e와 abcde를 가져 가라. 문법이 구문을 분석하는 방법에는 두 가지가 있지만, 우리가 사용하는 한 가지 방법이 있습니다.

"dangling else"의 경우 사람들이 실제로 그것을 보는 방식이 아닙니다. 대신 구문은 "if", 0, 하나 이상의 "else if", 선택적 "else"로 해석됩니다.


"if… then… else if ... then ... else if ... then… else ..."는 acbacbacbc내 표기법에서 : 이것은 초기 문법 (및 내가 동의하는 변형)에 의해 모호하게 구문 분석되므로 이에 대한 대안 구문 분석을 요구하지 않습니다.
Gro-Tsen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.