
"처음에 성공하지 못하면 시도하고 다시 시도하십시오"라는 격언은 역추적 .역추적은 matcher가 일치할 수 있는 모든 가능한 조합을 확인하는 방법입니다.이 게시물은 JMP의 패턴 매처에 있는 몇 가지 비밀 기능을 사용하여 역추적 프로세스를 노출합니다. 아래의 단일 문은 적당히 복잡한 패턴 일치입니다.그러나 간단한 일치(및 정규식)도 역추적을 사용합니다.
비밀 1: 21행의 Log() 함수는 JMP 로그 창에 출력을 생성합니다. >> 이전에 일치한 텍스트를 가져와서 소스의 0부터 시작하는 위치와 제공된 텍스트 레이블과 함께 인쇄합니다. 이것은 역추적 및 디버깅과 관련된 모든 것과 관련이 없습니다. 이 비밀을 사용하여 고유한 패턴을 디버그할 수 있습니다.
비밀 2: PatTest()에는 세 개의 인수가 있지만 하나만 사용됩니다. 이것은 모두 역추적에 관한 것입니다. 두 번째 인수의 JSL은 정방향으로 실행되고 세 번째 인수의 JSL은 역추적 방향으로 실행됩니다.
비밀 3: PatMatch()는 일반적으로 가능한 한 실패를 최적화합니다. 패턴의 나머지 최소 길이와 일치하기 위해 소스 문자열에 남아 있는 텍스트가 충분하지 않음을 확인하면 중지됩니다. FULLSCAN 옵션은 해당 최적화를 끕니다. 이 예의 경우 FULLSCAN 옵션이 없으면 역추적이 조기에 중지되는 것처럼 보입니다.
비밀 4: PatFail()은 각 일치를 강제로 실패시키고 대안을 고려하여 가능한 모든 일치를 찾는 데 사용할 수 있습니다.
아래에 설명과 함께 코드와 출력이 있습니다.
Pat Match(
"EDACGDE", // a contrived string to exercise backtracking
(
Pat Len( 1 ) >> p // match a character, store in p
+
Pat Test(
p > "B", // test
Write( "p=", p, " " ), // advance
Write( "retry\!n" ) // backtrack
)
+
Pat Arb() // skip zero or more characters
+
Pat Len( 1 ) >> q // match another, store in q
+
Pat Test(
p < q & q < "F", // test
Write( "q=", q, " " ), // advance
Write( "retry " ) // backtrack
)
) >> Log( "FOUND" ) // a debugging tool
+
Pat Fail(), // try alternatives
NULL, // no replacement
FULLSCAN // to the bitter end
);
p=E q=D 재시도 q=A 재시도 q=C 재시도 q=G 재시도 q=D 재시도 q=E 재시도
p=D q=A 재시도 q=C 재시도 q=G 재시도 q=D 재시도 q=E
1(찾음) DACGDE
재시도 재시도
p=재시도
p=C q=G 재시도 q=D
3(찾음) CGD
재시도 q=E
3(찾음) CGDE
재시도 재시도
p=G q=D 재시도 q=E 재시도 재시도
p=D q=E
5(찾음) 드
재시도 재시도
p=E 재시도
0
설명
첫째, 마지막 0입니다. 그것이 반환 코드이며 일치가 실패했다고 말합니다. 경기는 실제로 설립하다 4개의 일치 항목이 있지만 PatFail()이 다른 항목을 찾도록 했습니다. 이것은 예상됩니다.
다음은 P와 Q입니다. p는 E에서 시작하고 >B에 대한 테스트는 만족합니다. PatArb()는 꺼려하며 처음에는 아무 것도 건너뛰지 않습니다. q는 E 다음에 D를 얻습니다. 그러나 이번에는 테스트가 만족스럽지 않습니다. p와 "F" 사이의 q는 참이 아닙니다. 되돌릴 시간입니다! D를 q에 넣은 LEN(1)은 D를 되돌려주고 PatArb()는 다른 일을 할 기회를 줍니다. 이번에는 마지못해 D라는 문자 하나를 사용합니다. 그런 다음 PatLen(1)은 A를 q로 제공합니다. 첫 번째 줄의 끝에 두 번의 재시도가 있습니다. 두 번째는 p에 대한 것입니다. 다음 줄은 p가 두 번째 문자 D를 가져오는 것을 보여줍니다. 패턴 일치가 고정되어 있지 않기 때문에 일치 시작 부분이 역추적 프로세스의 일부로 텍스트를 통해 앞으로 떠오를 수 있습니다. 이번에는 PatArb가 첫 번째 성공을 거둘 때까지 점점 더 많은 것을 가져가면서 경기가 진행됩니다. >>Log("FOUND")는 성공을 로그에 기록하고 PatFail()은 역추적을 계속하도록 합니다.
명확하지 않은 경우 더 간단한 테스트를 시도하고 >>LOG("tag") 메서드로 계측하여 무슨 일이 일어나고 있는지 알 수 있습니다.
이 시점에서 이 경기가 매우 오랜 시간 동안 진행되는 이유가 분명해야 합니다.

aaaa...aaa의 문자열은 어디에도 b가 없기 때문에 성공할 수 없다는 것을 알 수 있지만 매처는 어리석은 조합을 많이 시도하여 발견해야 합니다. 2개의 문자를 건너뛰고 3을 건너뛰고... 다음으로 건너뛰기 2... 등, 등... 역추적은 잘못 작성된 패턴을 고칠 수 없습니다. 진행률 표시줄이 거의 완료되었음을 의미하지는 않습니다. (이 대화상자를 보기 위해서를 제외하고는 patrepeat 안에 patarb를 넣을 이유가 없습니다. Patarb는 이미 임의의 수의 문자와 일치합니다.)
2017년 2월 1일 업데이트 - 새 커뮤니티의 서식을 복구합니다.