둘러보기가 정규 표현식과 일치시킬 수있는 언어에 영향을 줍니까?


78

최신 정규식 엔진에는 해당 기능 없이는 일치시킬 수없는 언어를 일치시킬 수있는 몇 가지 기능이 있습니다. 예를 들어 역 참조를 사용하는 다음 정규식은 반복되는 단어로 구성된 모든 문자열의 언어와 일치합니다.(.+)\1 .. 이 언어는 규칙적이지 않으며 역 참조를 사용하지 않는 정규식과 일치시킬 수 없습니다.

둘러보기는 정규 표현식과 일치시킬 수있는 언어에도 영향을 미칩니 까? 즉, 그렇지 않으면 일치 할 수없는 lookaround를 사용하여 일치시킬 수있는 언어가 있습니까? 그렇다면 모든 종류의 룩 어라운드 (부정적 또는 긍정적 인 룩어 헤드 또는 룩 비하인드)에 해당됩니까, 아니면 일부에만 해당됩니까?


4
regular-expressions.info/lookaround.html 은 "Lookarounds를 사용하면 정규 표현식 없이는 만들 수 없거나 정규 표현식 없이는 매우 길어질 수있는 정규 표현식을 만들 수 있습니다"라고 말합니다. 그러나 그 방향에있는 유일한 예는하기 불가능 관한 찾아 일치 q는 a로 따르지 않는 . 입력 문자열이 있으면 말할 수 있는지에 대해 아무것도 말하지 않는다 포함 Q a로 따르지 유를 (단지 것을 일치하지 않고 Q ).
Christian Semrau 2010

7
@ChristianSemrau : 프로그래밍 질문 자체가 아닐 수도 있지만 요구 사항은 "프로그래밍 관련 "일 뿐이며 이것이 자격이 있다고 생각합니다. 그리고 저에게이 질문은 프로그래밍 중에 나온 실용적인 관점에서 실제로 흥미 롭습니다.
sepp2k

2
@Christian Semrau : "프로그래밍 관련"에 대한 나의 주요 기준은 질문이 유사한 회계 사이트 (명백한 간단한 대체 포함)에있는 것인지 여부입니다. 정규식은 매우 엄격하게 프로그래밍하는 것입니다. 저는 개인적으로 주제에 대해 생각합니다.
David Thornley 2010-06-07

5
분명히 CS가 stackoverflow에 속하는지 여부에 대한 질문은 meta.stackexchange.com/questions/26889/… 전에 논의되었습니다 . 개인적으로 여기에서 더 많은 CS 질문을 보거나 필요한 경우 자매 사이트를보고 싶습니다.
polygenelubricants 2010 년

답변:


25

다른 답변에서 주장했듯이 둘러보기는 정규 표현식에 추가 기능을 추가하지 않습니다.

다음을 사용하여 이것을 보여줄 수 있다고 생각합니다.

Pebble 2-NFA 1 개 (이를 참조하는 문서의 소개 섹션 참조).

1-pebble 2NFA는 중첩 된 lookaheads를 처리하지 않지만, multi-pebble 2NFA의 변형을 사용할 수 있습니다 (아래 섹션 참조).

소개

2-NFA는 입력에서 왼쪽 또는 오른쪽으로 이동할 수있는 능력이있는 비 결정적 유한 오토 마톤입니다.

하나의 조약돌 기계는 기계가 입력 테이프에 조약돌을 놓고 (즉, 조약돌로 특정 입력 기호를 표시) 현재 입력 위치에 조약돌이 있는지 여부에 따라 다른 전환을 수행 할 수있는 곳입니다.

One Pebble 2-NFA는 일반 DFA와 동일한 힘을 가지고있는 것으로 알려져 있습니다.

비 중첩 미리보기

기본 아이디어는 다음과 같습니다.

2NFA를 사용하면 입력 테이프에서 앞뒤로 이동하여 역 추적 (또는 '전면 트랙') 할 수 있습니다. 따라서 예견을 위해 예견 정규식에 대한 일치를 수행 한 다음 예견 식을 일치시킬 때 사용한 것을 역 추적 할 수 있습니다. 역 추적을 멈출 때를 정확히 알기 위해 우리는 조약돌을 사용합니다! 역 추적을 중지해야하는 지점을 표시하기 위해 미리보기를 위해 dfa에 들어가기 전에 조약돌을 떨어 뜨립니다.

따라서 조약돌 2NFA를 통해 문자열을 실행하는 마지막에, 우리는 미리보기 표현식과 일치하는지 여부를 알고 있으며 입력 왼쪽 (즉, 소비 될 남은 것)이 나머지와 일치하는 데 필요한 것이 정확히 무엇인지 압니다.

따라서 u (? = v) w 형식의 예견을 위해

u, v 및 w에 대한 DFA가 있습니다.

u에 대한 DFA의 수락 상태 (예, 하나만 있다고 가정 할 수 있음)에서 입력을 조약돌로 표시하여 시작 상태 v로 전자 전환합니다.

v에 대한 수락 상태에서 조약돌을 찾을 때까지 입력을 계속 왼쪽으로 이동하는 상태로 전자 전환 한 다음 w의 시작 상태로 전환합니다.

거부 상태 v에서 우리는 조약돌을 찾을 때까지 계속 왼쪽으로 이동하는 상태로 전자 전환하고 u의 허용 상태 (즉, 중단 한 위치)로 전환합니다.

일반 NFA가 r1을 표시하는 데 사용되는 증명 | r2 또는 r * 등은이 하나의 조약돌 2nfa에 대해 이월됩니다. 더 큰 시스템을 제공하기 위해 구성 요소 시스템을 조합하는 방법에 대한 자세한 내용은 http://www.coli.uni-saarland.de/projects/milca/courses/coal/html/node41.html#regularlanguages.sec.regexptofsa 를 참조하십시오 . r * 표현식 등

위의 r * 등 증명이 작동하는 이유는 반복을 위해 구성 요소 nfas를 입력 할 때 입력 포인터가 항상 올바른 지점에 있도록 역 추적을 수행하기 때문입니다. 또한 조약돌이 사용 중이면 미리보기 구성 요소 시스템 중 하나에서 처리 중입니다. 완전히 역 추적하고 조약돌을 되찾지 않고는 예견 기계에서 예견 기계로의 전환이 없기 때문에 하나의 조약돌 기계 만 있으면됩니다.

예를 들어 ([^ a] | a (? = ... b)) *

그리고 문자열 abbb.

a (? = ... b)에 대한 peb2nfa를 통과하는 abbb가 있으며, 그 끝에는 상태 : (bbb, matched) (즉, 입력 bbb가 남아 있고 'a'와 일치했습니다. 뒤에 '..b'). 이제 * 때문에 처음으로 돌아가서 (위 링크의 구성 참조) [^ a]에 dfa를 입력합니다. b를 일치시키고 처음으로 돌아가서 [^ a]를 다시 두 번 입력 한 다음 수락합니다.

중첩 된 Lookahead 처리

중첩 된 미리보기를 처리하기 위해 여기에 정의 된대로 제한된 버전의 k-pebble 2NFA를 사용할 수 있습니다. 양방향 및 다중 페블 오토마타와 그 논리에 대한 복잡성 결과 (정의 4.1 정리 4.2 참조).

일반적으로 2 개의 pebble automata는 비정규 세트를 수용 할 수 있지만, 다음과 같은 제한 사항으로 인해 k-pebble automata는 규칙적인 것으로 표시 될 수 있습니다 (위 논문의 Theorem 4.2).

자갈이 P_1, P_2, ..., P_K 인 경우

  • P_i가 이미 테이프에 있지 않으면 P_ {i + 1}을 배치 할 수없고 P_ {i + 1}이 테이프에 없으면 P_ {i}를 선택할 수 없습니다. 기본적으로 자갈은 LIFO 방식으로 사용되어야합니다.

  • P_ {i + 1}이 배치 된 시간과 P_ {i}가 선택되거나 P_ {i + 2}가 배치되는 시간 사이에 오토마타는 P_ {i}의 현재 위치 사이에있는 하위 단어 만 횡단 할 수 있습니다. 그리고 P_ {i + 1} 방향에있는 입력 단어의 끝. 또한이 하위 단어에서 오토 마톤은 Pebble P_ {i + 1}과 함께 1 조약돌 오토 마톤으로 만 작동 할 수 있습니다. 특히 다른 조약돌의 존재를 들어올 리거나 배치하거나 감지 할 수 없습니다.

따라서 v가 깊이 k의 중첩 된 미리보기 표현식이면 (? = v)는 ​​깊이 k + 1의 중첩 된 미리보기 표현식입니다. 내부 예견 기계에 들어가면 지금까지 얼마나 많은 조약돌을 놓아야하는지 정확히 알고 있으므로 어떤 조약돌을 놓을 지 정확하게 결정할 수 있고 그 기계에서 나올 때 어떤 조약돌을 들어 올릴 것인지 알 수 있습니다. 깊이 t에있는 모든 기계는 조약돌 t를 배치하여 들어가고 조약돌 t를 제거하여 나갑니다 (즉, 깊이 t-1 기계의 처리로 돌아갑니다). 전체 머신의 모든 실행은 트리의 재귀 dfs 호출처럼 보이며 위의 두 가지 제한 사항을 충족 할 수 있습니다.

이제 표현식을 결합 할 때 rr1에 대해 연결하므로 r1의 조약돌 수는 r의 깊이만큼 증가해야합니다. r * 및 r | r1의 경우 조약돌 번호는 동일하게 유지됩니다.

따라서 미리보기가있는 모든 표현은 조약돌 배치에 위의 제한 사항이있는 동등한 다중 조약돌 기계로 변환 될 수 있으므로 규칙적입니다.

결론

이것은 기본적으로 Francis의 원래 증명의 단점을 해결합니다. 예견 표현이 향후 경기에 필요한 모든 것을 소비하는 것을 방지 할 수 있다는 것입니다.

Lookbehind는 유한 문자열 (정규식이 아님) 일 뿐이므로 먼저 처리 한 다음 미리보기를 처리 할 수 ​​있습니다.

불완전한 글을 써서 미안하지만 완전한 증거에는 많은 그림을 그리는 것이 포함됩니다.

나에게는 옳게 보이지만 실수를 알고 있으면 기쁠 것입니다 (내가 좋아하는 것 같습니다 :-)).


이것이 여러 개의 미리보기를 처리하는지 확실 u(?=v)(?=w)(?=x)z하지 않습니다.
Francis Davey

예견을 위해 조약돌 2NFA를 종료하면 사용할 조약돌과 함께 입력 테이프 상태로 돌아갑니다. 일치하는 것이 있는지 말하십시오). 그래서 그것은 우리가 항상 조약돌을 되 찾는 것처럼 automata (우리가 추가 한 e-transitions와 함께 추가 상태와 함께)를 연결함으로써 작동하는 것처럼 보입니다. 하지만 그 표현을 어떻게 해석 하느냐에 달려 있다고 생각합니다. u (? = vwx) z와 동일합니까? 또는 ((u (? = v))? = w) ... 등?

이 표현식은 v, w 및 x (여기서 v, w 및 x는 모두 일반 정규 표현식) 및 z가 뒤따라야하는 (소비되지 않음) au와 일치합니다. 이 문제를 해결할 무언가를 만들려고 시도한 결과, 구성 적으로 (즉, 솔루션을 연결하여) 할 수 없다고 상당히 확신합니다.
Francis Davey

@Francis : 모두 일치해야하는 경우 연결이 작동합니다 (내 생각에). 우리는 그것을 dfa (u)-> peb2ndfa (v)-> peb2ndfa (w)-> dfa (x)로 연결합니다. u를 일치시킨 후 v 또는 w가 일치하지 않으면 u로 돌아가서 중단 한 부분을 선택합니다. v와 일치하면 v가 완료된 후 역 추적하기 때문에 w를 다시 일치시키고 (다시 역 추적 함) x를 일치시킬 수 있습니다. 핵심은 2NDFA를 통해 우리가 역 추적을 할 수 있고 조약돌이 역 추적을 중지 할 때를 알 수 있다는 것입니다.

@ sepp2k :이 답변을 읽을 기회를 얻었습니까? 질문 / 설명 / 반례가 있으면 기꺼이 답변 해 드리겠습니다.

27

정규 언어보다 더 큰 언어 클래스를 둘러보기에 의해 확장 된 정규 표현식으로 인식 할 수 있는지 묻는 질문에 대한 대답은 '아니요'입니다.

증명은 비교적 간단하지만 둘러보기를 포함하는 정규식을없는 것으로 변환하는 알고리즘은 지저분합니다.

첫째 : 유한 알파벳을 통해 정규 표현식을 항상 부정 할 수 있습니다. 표현식에 의해 생성 된 언어를 인식하는 유한 상태 오토 마톤이 주어지면 모든 허용 상태를 비 수락 상태로 간단히 교환하여 해당 언어의 부정을 정확히 인식하는 FSA를 얻을 수 있습니다. 이에 상응하는 정규 표현식 제품군이 있습니다. .

둘째 : 정규 언어 (및 정규 표현식)가 부정으로 닫히기 때문에 A가 드 모건의 법칙에 따라 B = neg (neg (A) union neg (B))를 교차하므로 교차로에서도 닫힙니다. 즉, 두 개의 정규식이 주어지면 둘 다 일치하는 다른 정규식을 찾을 수 있습니다.

이를 통해 둘러보기 표현식을 시뮬레이션 할 수 있습니다. 예를 들어 u (? = v) w는 uv 및 uw와 일치하는 표현식 만 일치합니다.

부정 예견의 경우 집합 이론 A \ B에 해당하는 정규식이 필요합니다. 즉, A는 교차 (neg B) 또는 동등하게 neg (neg (A) union B)입니다. 따라서 정규식 r 및 s에 대해 s와 일치하지 않는 r과 일치하는 표현식과 일치하는 정규식 rs를 찾을 수 있습니다. 부정적 예측 용어로 : u (?! v) w는 uw-uv와 일치하는 표현식 만 일치합니다.

둘러보기가 유용한 이유는 두 가지입니다.

첫째, 정규 표현식의 부정은 훨씬 덜 깔끔한 결과를 가져올 수 있기 때문입니다. 예를 들면q(?!u)=q($|[^u]) .

둘째, 정규식은 일치 식 이상의 기능을 수행하며 문자열에서 문자를 소비합니다. 또는 적어도 우리가 생각하는 방식입니다. 예를 들어 파이썬에서는 .start () 및 .end ()에 대해 신경을 쓰고 있습니다.

>>> re.search('q($|[^u])', 'Iraq!').end()
5
>>> re.search('q(?!u)', 'Iraq!').end()
4

셋째, 이것이 매우 중요한 이유라고 생각합니다. 정규 표현식의 부정은 연결보다 잘 들어 맞지 않습니다. neg (a) neg (b)는 neg (ab)와 동일하지 않습니다. 즉, 찾은 컨텍스트에서 둘러보기를 번역 할 수 없습니다. 전체 문자열을 처리해야합니다. 나는 사람들이 작업하는 것을 불쾌하게 만들고 정규 표현식에 대한 사람들의 직관을 깨뜨린다고 생각합니다.

나는 당신의 이론적 질문에 대답하기를 바랍니다 (밤 늦게, 불분명하면 용서하십시오). 나는 이것이 실제적인 응용이 있다고 말한 해설자에 동의합니다. 매우 복잡한 웹 페이지를 긁어 모 으려고 할 때 매우 동일한 문제를 만났습니다.

편집하다

명확하지 않은 것에 대해 사과드립니다. 구조적 유도에 의해 정규식 + 둘러보기의 정규성 증명을 제공 할 수 있다고 믿지 않습니다. 제 u (?! v) w 예제는 그저 예이고 쉬운 예입니다. 그것에. 구조적 유도가 작동하지 않는 이유는 둘러보기가 비구 성적인 방식으로 작동하기 때문입니다. 위의 부정에 대해 제가 말씀 드렸던 요점입니다. 나는 어떤 직접적인 공식적인 증명이 복잡한 세부 사항을 많이 가질 것이라고 생각합니다. 나는 그것을 보여줄 쉬운 방법을 생각했지만 내 머리 꼭대기에서 하나를 생각할 수 없다.

Josh의 첫 번째 예제 사용을 설명 ^([^a]|(?=..b))*$하기 위해 모든 주가 다음을 수락하는 7 개 주 DFSA와 동일합니다.

A - (a) -> B - (a) -> C --- (a) --------> D 
Λ          |           \                  |
|          (not a)       \               (b)
|          |              \               | 
|          v                \             v
(b)        E - (a) -> F      \-(not(a)--> G  
|            <- (b) - /                   |
|          |                              |
|         (not a)                         |
|          |                              |
|          v                              |
\--------- H <-------------------(b)-----/

상태 A에 대한 정규식은 다음과 같습니다.

^(a([^a](ab)*[^a]|a(ab|[^a])*b)b)*$

즉, 둘러보기를 제거하여 얻을 정규식은 일반적으로 훨씬 길고 더 지저분해질 것입니다.

Josh의 의견에 응답하기 위해-그렇습니다. 동등성을 증명하는 가장 직접적인 방법은 FSA를 통하는 것입니다. 이것을 더 복잡하게 만드는 것은 FSA를 구성하는 일반적인 방법이 비 결정적 기계를 통한다는 것입니다. u | v를 두 기계로 엡실론으로 전환하여 u와 v를 위해 기계로 구성한 기계처럼 간단하게 u | v를 표현하기가 훨씬 쉽습니다. 물론 이것은 결정 론적 기계와 동일하지만 상태가 기하 급수적으로 폭발 할 위험이 있습니다. 부정은 결정 론적 기계를 통해 수행하는 것이 훨씬 쉽습니다.

일반적인 증명에는 두 기계의 데카르트 곱을 취하고 둘러보기를 삽입하려는 각 지점에서 유지하려는 상태를 선택하는 것이 포함됩니다. 위의 예는 내가 의미하는 바를 어느 정도 보여줍니다.

공사를 제공하지 않은 것에 대해 사과드립니다.

추가 편집 : 블로그 게시물 을 찾았 습니다. 둘러보기가 추가 된 정규 표현식에서 DFA를 생성하는 알고리즘을 설명하는 을 습니다. 저자가 "태그 된 엡실론 전환"으로 NFA-e의 아이디어를 명백한 방식으로 확장 한 다음 이러한 자동 장치를 DFA로 변환하는 방법을 설명하기 때문에 깔끔합니다.

그렇게하는 것이 방법이라고 생각했지만 누군가가 그것을 써서 기쁩니다. 그렇게 깔끔한 것을 생각해내는 것은 저를 넘어 섰습니다.


2
나는 주위를 둘러 보는 것이 규칙적이라는 Francis와 동의하지만 그 증거가 틀렸다고 생각합니다. 문제는 일반적으로 두 개의 정규식 A와 B로 둘러 보는 정규식을 분리 할 수 ​​없다는 것입니다. Francis는 및 로 변환 u(?!v)w하여 그렇게 했지만 일반적으로이를 수행하는 알고리즘이 존재한다고 생각하지 않습니다. 대신 엡실론 전환과 함께 발생하는 지점에서 원본 DFA에 예견 또는 부정 (예측)을 첨부 할 수 있습니다. 이것에 대한 세부 사항은 약간 까다 롭지 만 작동한다고 생각합니다. uwuv
Josh Haberman

1
예를 들어 regex를 고려하십시오 ^([^a]|a(?=..b))*$. 즉, 모든 문자가 허용되지만 모든 "a"는 나중에 "b"와 함께 3 자 뒤에 와야합니다. 나는 이것을 결합을 통해 결합하는 두 개의 정규식 A와 B로 줄일 수 있다고 생각하지 않습니다. NFA 구성의 긍정적 인 예견 부분을 만들어야한다고 생각합니다.
Josh Haberman

1
@Josh, sepp2k : 모든 정규 언어 L에 대해 동등한 정규 표현식이 있으며 그 반대도 마찬가지입니다. 이제 a (? = .. b)는 규칙적이며 r과 같은 일부 표현식에 해당합니다. 이제 ([^ a] | r) *가 생겼습니다. 이것은 다시 규칙적입니다. 나는 이것이 Kleene에 의해 입증되었다고 믿습니다. 이것을 확인하십시오 : coli.uni-saarland.de/projects/milca/courses/coal/html/… . 귀납법에 의한 증명은 효과가 있습니다. 당신이 매달린 것처럼 보이는 것은 정규 표현식과 언어에 대한 근본적인 사실입니다 (이 주석의 첫 번째 문장).

3
@Moron : 예견식이 정규식과 동일한 방식으로 구성된다고 가정합니다. 당신은 그 추정되는 ([^a]|r)*언어와 동일한 언어와 일치 ([^a]|a(?=..b)), 사실이 아니다을 경우에도, r경기 같은 언어로 a(?=..b). DFA 확장을 직접 수행하면 볼 수 있습니다. 미리보기는 문자를 소비하지 않고 문자와 일치시키기 때문에 정규 표현식과 같은 방식으로 구성하지 않습니다. 그래도 확신이 서지 않으시면 나중에 실제 DFA 확장을 게시하겠습니다.
조쉬 Haberman

2
이 짧은 증거로, 그 생각 a(?=..b)때문에, 비어있는 언어입니다 a ∩ a..b = ϵ. 그래서 우리는 추론의 당신의 라인을 따르는 경우 r = ϵ([^a]|a(?=..b))*동등하다 ([^a]|ϵ)*하거나 [^a]*. 그러나 이것은 aaab원래 정규식과 일치하지만 아마도 동등한 정규식과 일치하지 않기 때문에 분명히 거짓 입니다.
Josh Haberman

10

나는 둘러보기가 정규적이라는 다른 게시물에 동의하지만 (정규 표현식에 기본 기능을 추가하지 않는다는 의미), 내가 본 다른 게시물보다 IMO가 더 간단하다는 주장이 있습니다.

DFA 구성을 제공하여 둘러보기가 규칙적임을 보여 드리겠습니다. 언어는이를 인식하는 DFA가있는 경우에만 일반 언어입니다. Perl은 실제로 내부적으로 DFA를 사용하지 않지만 (자세한 내용은이 문서 참조 : http://swtch.com/~rsc/regexp/regexp1.html ) 증명을 위해 DFA를 구성합니다.

정규 표현식을위한 DFA를 구성하는 전통적인 방법은 먼저 Thompson의 알고리즘을 사용하여 NFA를 구축하는 것입니다. 두 개의 정규식 조각 r1과가 주어지면 r2Thompson의 알고리즘은 정규식 의 연결 ( r1r2), 교대 ( r1|r2) 및 반복 ( r1*)에 대한 구성을 제공합니다 . 이를 통해 원래 정규 표현식을 인식하는 NFA를 비트별로 빌드 할 수 있습니다. 자세한 내용은 위의 문서를 참조하십시오.

긍정 및 부정 예견이 규칙적임을 보여주기 위해 정규식 u을 긍정 또는 부정 예견과 연결하는 구성을 제공합니다 . (?=v)또는 (?!v). 연결에만 특별한 처리가 필요합니다. 일반적인 교대 및 반복 구조는 잘 작동합니다.

구성은 u (? = v)와 u (?! v) 모두 다음과 같습니다.

http://imgur.com/ClQpz.png

즉,에 대한 기존 NFA의 모든 최종 상태를 u수락 상태 에 대한 NFA 모두 v에 연결하지만 다음과 같이 수정합니다. 함수 f(v)는 다음과 같이 정의됩니다.

  • 모든 수락 상태를 "수락 방지 상태"로 변경 aa(v)하는 NFA의 함수가 되자 v. 안티 수락 상태가 실패 할 경기를 일으키는 상태로 정의 된 경우 어떤 주어진 문자열이 상태에서 NFA의 끝을 통해 경로 s,해도를 통해 다른 경로 v에 대한 saccept를 상태로 종료된다.
  • 하자 loop(v)NFA의 함수가 될 수 v있는 상태가 동의에 자체 전환을 추가합니다. 즉, 경로가 수락 상태에 도달하면 해당 경로는 어떤 입력이 뒤 따르더라도 영원히 수락 상태를 유지할 수 있습니다.
  • 부정적인 예측의 경우 f(v) = aa(loop(v)).
  • 긍정적 인 예측의 경우 f(v) = aa(neg(v)).

이것이 작동하는 이유에 대한 직관적 인 예를 제공하기 위해 나는 (b|a(?:.b))+Francis의 증명에 대한 주석에서 제안한 정규식의 약간 단순화 된 버전 인 regex를 사용할 것입니다. 전통적인 Thompson 구조와 함께 내 구조를 사용하면 다음과 같이 끝납니다.

대체 텍스트

e들 엡실론 전환 (전환 모든 입력을 사용하지 않고 촬영 할 수있다)하고있는 상태가 함께 표시되어 안티 동의 X. 그래프의 왼쪽 절반에서 다음과 같은 표현을 볼 수 있습니다 (a|b)+. any a또는 b그래프를 수락 상태로 설정하지만 다시 시작할 수 있도록 시작 상태로 다시 전환 할 수도 있습니다. 그러나 일치 할 때마다 a그래프의 오른쪽 절반에 들어가며 "any"다음에 b.

기존 NFA에는 반 수락 상태가 없기 때문에 이는 기존 NFA가 아닙니다. 그러나 기존 NFA-> DFA 알고리즘을 사용하여이를 기존 DFA로 변환 할 수 있습니다. 알고리즘은 평소와 같이 작동합니다. 여기서 DFA 상태를 우리가있을 수있는 NFA 상태의 하위 집합에 해당하도록하여 NFA의 여러 실행을 시뮬레이션합니다. 한 가지 문제는 DFA 상태가 다음과 같은지 여부를 결정하는 규칙을 약간 강화한다는 것입니다. (최종) 상태를 수락할지 여부. 기존의 알고리즘에서 DFA 상태는 경우가 상태를 받아 들일 것입니다 어떤 NFA의 상태가 상태가 동의했다. 다음과 같은 경우에만 DFA 상태가 수락 상태임을 나타내도록 수정합니다.

  • = 1 NFA 상태는 수락 상태 이고

  • 0 NFA 상태는 반 수락 상태입니다.

이 알고리즘은 미리보기로 정규 표현식을 인식하는 DFA를 제공합니다. Ergo, 예견은 규칙적입니다. lookbehind에는 별도의 증명이 필요합니다.


당신이 준 기계에서 당신은 a. (b | a (? =. b))에 없습니다. 또한 반 수락 상태는 일치가 실패하는 수락 상태입니까? 그런 다음 수락 상태의 정의에 따라 수락 거부 상태가 없습니다! 아니면 내가 뭔가를 놓치고 있습니까?

@Moron : 당신은 나의 반-수락 상태의 의미를 놓치고 있다고 생각합니다. 다음은 동일한 다이어그램이지만 번호가 매겨진 상태는 다음과 같습니다. imgur.com/ho4C8.png 내 시스템 은를 허용하지 않습니다. a일치 후 a상태 4, 3, 1 및 5로 전환 할 수 있기 때문입니다 (NFA-> DFA 알고리즘 사용). 그러나 상태 5는 수락 금지 상태이므로 필자의 글 맨 아래에있는 규칙에 따라 상태 4, 3, 1 및 5에 해당하는 DFA 상태 는 수락 상태 가 아닙니다 .
Josh Haberman

@Josh : 정의가 aa(v)문자열 에 의존 하지 s않습니까? 즉, 세트 aa(v)s. 또한 당신은 반-수락 상태가 수용 상태에서 시작한다고 말합니다. 그렇다면 기계가 그 상태로 끝나면 어떻게 일치가 실패 할 수 있습니까? 내가 잘못 읽고 있다면 죄송합니다.

@Moron : aa(v)대신 모든 수락 상태를 수락 금지 상태로 뒤집기 때문에 s. v및 둘 다 aa(v)NFA이며 세트가 아닙니다. 나는 귀하의 마지막 코멘트를 따르지 않습니다. v수락 상태가 있지만 수락 상태 aa(v)가 없으며 aa(v)실제로 최종 NFA에서 끝나는 것은 사실입니다.
Josh Haberman

@Josh : 귀하의 정의 : "Aa (v)가 모든 수락 상태를 수락 방지 상태로 변경하는 NFA v의 함수가되게하십시오 ..". 따라서 머신 v가 일부 실행에서 상태 P에서 끝나고 일치가 실패하면 수락 상태 P를 비 수락 상태로 변경합니다. 그러나 정의에 따라 (참고 v는 여전히 NFA 임) 허용 된 상태로, 머신이 거기서 종료되면 일치가 통과 된 것입니다! 그리고 제가 의미하는 세트는 v의 상태 세트를 반 수락으로 변경해야 v를 aa (v)로 만들 수 있습니다. 문자열에 의존하지 s않습니까? 이제 더 명확 해 졌으면합니다.

2

여기에 두 가지 질문이 있습니다.

  • "lookaround"를 통합하는 Regex 엔진이 그렇지 않은 Regex 엔진보다 더 강력합니까?
  • "lookaround"가 Chomsky Type 3-Regular 문법 에서 생성 된 것보다 더 복잡한 언어를 구문 분석 할 수있는 능력을 Regex 엔진에 부여 합니까?

실용적인 의미에서 첫 번째 질문에 대한 대답은 '예'입니다. Lookaround는이 기능을 사용하는 Regex 엔진에 기본적으로 그렇지 않은 엔진보다 더 많은 성능을 제공합니다. 이는 매칭 프로세스에 더 풍부한 "앵커"세트를 제공하기 때문입니다. Lookaround를 사용하면 전체 Regex를 가능한 앵커 포인트 (폭이 0 인 어설 션)로 정의 할 수 있습니다. 여기 에서이 기능의 강력한 기능에 대한 개요를 볼 수 있습니다 .

Lookaround는 강력하기는하지만 유형 3 문법에서 정한 이론적 한계를 넘어 Regex 엔진을 들어 올리지는 않습니다. 예를 들어, Lookaround가 장착 된 Regex 엔진을 사용하여 Context Free-Type 2 Grammar 를 기반으로하는 언어 를 안정적으로 구문 분석 할 수 없습니다. 정규식 엔진은 유한 상태 자동화 의 힘 으로 제한되며 이는 파싱 할 수있는 모든 언어의 표현력을 유형 3 문법 수준으로 근본적으로 제한합니다. Regex 엔진에 추가 된 "트릭"의 수에 관계없이 언어는 문맥 자유 문법을 항상 그 능력을 뛰어 넘을 것입니다. 구문 분석 자유-유형 2 문법은 재귀 언어 구조의 위치를 ​​"기억"하기 위해 푸시 다운 자동화가 필요합니다. 문법 규칙의 재귀 적 평가가 필요한 것은 Regex 엔진을 사용하여 구문 분석 할 수 없습니다.

요약하면 : Lookaround는 Regex 엔진에 몇 가지 실질적인 이점을 제공하지만 이론적 수준에서 "게임을 변경"하지는 않습니다.

편집하다

Type 3 (Regular)와 Type 2 (Context Free) 사이에 복잡한 문법이 있습니까?

대답은 '아니오'라고 생각합니다. 그 이유는 일반 언어를 설명하는 데 필요한 NFA / DFA의 크기에 이론적 인 제한이 없기 때문입니다. 임의로 커져서 사용 (또는 지정)하는 것이 비실용적 일 수 있습니다. 이것은 "둘러보기"와 같은 회피가 유용한 곳입니다. 이는 매우 크고 복잡한 NFA / DFA 사양으로 이어질 항목을 지정하는 간단한 메커니즘을 제공합니다. 그들은 정규 언어의 표현력을 증가시키지 않고 단지 그들을 더 실용적으로 지정합니다. 이 점을 이해하면 실용적인 의미에서 더 유용하게 만들기 위해 Regex 엔진에 추가 할 수있는 많은 "기능"이 있다는 것이 분명해집니다. 그러나 정규 언어의 한계를 넘어 설 수있는 것은 없습니다. .

Regular 언어와 Context Free 언어의 기본적인 차이점은 Regular 언어에는 재귀 요소가 포함되어 있지 않다는 것입니다. 재귀 언어를 평가하려면 재귀에있는 위치를 "기억"하는 푸시 다운 자동화가 필요합니다. NFA / DFA는 상태 정보를 스택하지 않으므로 재귀를 처리 할 수 ​​없습니다. 따라서 비재 귀적 언어 정의가 주어지면이를 설명하기위한 NFA / DFA (실용적인 정규식 표현 일 필요는 없음)가 있습니다.


1
일반 문법보다 더 강력한 문법이 문맥없는 것만 큼 강력해야한다는 것이 반드시 사실입니까? 즉. 둘 사이에 문법 이 없다는 것이 알려져 있습니까?
BlueRaja-Danny Pflughoeft 2010 년

@BlueRaja : 정확히 내가 생각했던 것 : '문법 연속체 가설':-)

@Moron @BlueRaja-나는 당신을 위해 내 대답을 편집했습니다. 도움이 되었기를 바랍니다.
NealB

4
물론 정규 문법 클래스와 문맥 자유 문법 클래스 사이에는 균형 잡힌 괄호 언어에 대한 문법과 함께 정규 문법 클래스와 같은 사소한 예를 포함하여 많은 클래스 클래스가 있습니다. 결정적 문맥 자유 문법이 더 유용한 예이다.
Christian Semrau 2010 년

An NFA/DFA does not stack state information so cannot handle the recursion.예. 따라서 정규식으로 HTML을 구문 분석하지 마십시오!
Cruncher
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.