LR 구문 분석을 사용한 순열 구


16

순열 구문은 표준 (E) BNF 컨텍스트 프리 문법 정의의 확장입니다. 순열 구문 에는 n 개의 프로덕션 (또는 이와 동일하게 비 터미널) A 1 - A n이 포함 됩니다. 순열 구의 위치에서, 우리는이 작품들 모두를 정확히 한 번보고 싶어하지만,이 비 터미널의 순서에는 관심이 없습니다.{1,,}1

예를 들면 다음과 같습니다.

S <- X { A, B, C } Y

다음과 같습니다.

S <- X  A B C  Y
S <- X  A C B  Y
S <- X  B A C  Y
S <- X  B C A  Y
S <- X  C A B  Y
S <- X  C B A  Y

이 개념은 "순열 구를 사용하여 문맥없는 문법 확장" 에서 소개 된 것으로 보입니다 . 여기에는 LL (1) 파서를 사용하여 이러한 구문을 선형 시간으로 구문 분석하는 방법도 설명되어 있습니다.

백서 "구문 분석 구문 분석"은 구문 분석기 조합기를 사용하여 순열 구문을 구문 분석하는 방법을 설명합니다. 이것들은 순열 구와 구문 분석 방법에 대해 이야기 한 유일한 두 논문입니다.

이러한 종류의 순열 구문을 LL (1) 기반 파서로 쉽게 구문 분석 할 수 있다는 것을 알면 LR (1) 스타일 파서로 동일한 작업을 수행 할 수있을 것입니다. 내 질문은 따라서 :

순열 구문을 포함하는 문법을 합리적인 크기의 테이블을 유지하면서 LR (1) 기계를 사용하여 입력 문자열 크기에서 시간 선형으로 구문 분석 할 수 있습니까?

순열 구는 문맥이없는 언어의 힘을 확장하지 않습니다. 위의 예에서와 같이 가능한 모든 순열을 간단히 열거 할 수 있습니다. 그러나 결과 문법의 크기가 수 있으므로 문법이 폭발합니다 . 이를 통해 선형 시간 구문 분석이 가능하지만 문법 크기가 너무 커집니다.영형(||!)

위의 접근 방식은 모든 구문 분석 알고리즘에서 작동하므로 (유용하지는 않지만) 특정 알고리즘에 대해 더 잘 수행 할 수 있습니다. 구문을 LR 테이블로 인코딩 하여 블로우 업을 '단순하게'지수 ( )로 줄일 수 있습니다. 순열 구.영형(2||)

이 방법이 더 좋지만 물론 충분하지는 않습니다. 순열 문구가 30 개이면 문법을 사용할 수 없게됩니다. 아직 다루지 않은 LR 파싱의 한 부분이 여전히 있으며, 파싱에 사용되는 실제 스택 기반 절차입니다. 스택에 카운터를 저장하면 문제를 해결할 수 있다고 생각하지만 어떻게 해야할지 모르겠습니다.

나는 현재 파서 생성기를 구현하고 있으며 문제 영역에서 순열 구는 천국의 선물이 될 것입니다. LR (1) 기계를 사용함에 따라 위의 질문이 이어졌습니다.


LR (1) 구문 분석의 복잡성은 치환 구문없이 문법의 크기에서 이미 기하 급수적입니다. 정품 LR (1)
Sylvain

2
나머지 질문에 대해 : cstheory.stackexchange.com/questions/4962/… 는 순열을위한 CFG의 크기에 대한 지수 하한을 보여 주며 PDA에서 CFG의 일반적인 다항식 구성을 통해 지수 하한을 수반합니다. PDA의 크기도 마찬가지입니다.
Sylvain

1
나는 LL (1)에 관한 논문을 보지 않았다. 실제로, 구현 된 파서는 더 이상 PDA가 아니다. 정황에 맞는 문맥없는 문법의 멤버쉽이 NP- 완료이기 때문에 ( "예 : dx.doi.org/10.3233/FI-1997-3112" 참조 ), 여전히 "합리적인 크기의 테이블"이 있다고 믿지는 않지만 사실입니다. 하드 인스턴스는 LR (1)이 아닐 수 있습니다.
Sylvain

2
@ 실뱅 : 질문 4962가이 질문과 어떤 관련이 있는지 자세히 설명해 주시겠습니까? 문제 4962에서 각 입력 길이에 대해 순열이 고정되고 순열 될 문자열이 변경됩니다. 현재 질문에서는 순열을 수정하지 않습니다. 그래서 나는 그들 사이의 실제 연결을 보지 못했습니다.
Ito Tsuyoshi

2
@Tsuyoshito Ito : LR (1) 구문 분석에서 입력 문법에 해당하는 DPDA가 먼저 구성된 다음 문자열에 대해 인식되어 인식됩니다. 모든 순열 언어에 대한 순열 문구가 포함 된 선형 크기의 CFG가 있기 때문에 Yuval Filmus의 논문 (cstheory에 대한 그의 답변보다 포괄적 임 : cs.toronto.edu/~yuvalf/CFG-LB.pdf 참조 )은 그러한 DPDA는 입력 문법의 크기에서 다항식 크기 ​​일 수있다.
Sylvain

답변:


1

이것을 의미 론적 문제로 변환하는 것을 고려 했습니까? 비 터미널 {A, B, C}의 모든 순열에 대한 문법 규칙 대신, 각각 하나만 인식되도록하는 특별한 내부 코드와 함께 (A | B | C) ^ 3을 인식하는 규칙이 하나 있습니다. 그렇지 않으면 선언합니다. 오류. 위의 절 앞에 빈 프로덕션을 삽입하면 축소가 A, B 및 C를 계산하는 데 사용하는 모든 항목의 초기화가 트리거되고 그 이후에는 카운터 검사가 트리거되고 (필요한 경우) 오류가 발생합니다. (물론 문법이 A, B 및 / 또는 C를 통해 재귀 적 인 경우 약간 까다로울 수 있습니다)


0

카운터가 필요하다고 생각하지 않습니다. 본질적으로 모든 순열을 확인하지만 중단하십시오.

의사 코드 :

perm-match(input, pattern)
     if pattern = nil return true

     foreach(rule in pattern)
         if (match(input, rule))
             perm-match(input - matchedpart, pattern - rule)
             break
         end
     end
     return false
end

보다 구체적인 예는 다음과 같습니다.

abcd의 순열과 일치 시키려고하고 문자열이 bcda라고 가정합니다.

  • 1 단계 : 첫 번째 일치하는 기호 찾기 이 경우에는 b
  • 2 단계 : 패턴에서 해당 심볼을 제거하고 문자열을 줄입니다. 예 : acd 및 cda
  • 3 단계 : 새 문자열에서 1 단계를 반복하십시오.
    • c는 cda와 일치하여 ad와 da로 우리를 떠납니다.
    • 우리를 d와 d로 만드는 da의 일치
    • d는 d와 일치하여 두 문자열에서 모두 nil로 남습니다.

따라서이 간단한 알고리즘은 단순히 "문자열"을 순서대로 비교하여 순열을 쉽게 확인할 수 있습니다. 함수의 복잡성은 O (n!) 더 나쁜 경우와 O (1) 가장 좋은 경우입니다. 어떤 의미에서 우리는 배열에 일치하는 기호를 저장하여 카운트를 유지합니다. 대부분의 경우 매우 큰 n을 처리하지 않기 때문에 이것이 일반적으로 "빠른"것이라고 생각합니다.


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