2017-10-17 14 views
0

처음부터 파서 연결자 용 터미널 파서를 만들려고합니다. 내 접근 방식은 입력 문자열에 regexp-match-positions*을 사용하고 패턴이 첫 번째 위치에서 발견되면 분할 문자열을 출력합니다.문자열 시작 부분의 정규 표현식으로 일치 및 분할

이것은 지금까지 내가있어 무엇 :

#lang racket/base 

(require racket/match) 

(define (make-terminal-parser pattern) 
    (define (regexp-match-from-start pattern input) 
    (match (regexp-match-positions* pattern input) 
     [(list (cons 0 x) ...) 
     (let ([index (car x)]) 
      (values (substring input 0 index) 
        (substring input index)))] 

     [_ (error "Not found!")])) 

    (lambda (input) 
    (regexp-match-from-start pattern input))) 

(define ALPHA (make-terminal-parser #rx"[a-zA-Z]")) 

(ALPHA "hello") 

ALPHA가 작동하지 않는 것 그리고 내가 때문에 아무것도 동일시하지 일치하는 패턴으로 생각합니다. REPL에서 (regexp-match-positions* #rx"[a-zA-Z]" "hello")은 내가 무엇을 기대하는지 ('((0 . 1) (1 . 2) etc.)) 출력하므로 (list (cons 0 x) ...)과 일치하지 않는 이유를 실제로 이해하지 못합니다. 정규 표현식을 #rx"h"으로 변경하면 올바르게 문자열이 분할됩니다. 그러나 이것은 분명히 너무 구체적입니다.

(관련 메모에 : 나는이 일치하는 단점에서 실제 인덱스 값을 얻을 (car x)에 필요한 이유를 이해하지 않습니다.)

답변

0

그것은 내 패턴이 참이었다 가졌다 문제를 밝혀 어울리는. (list (cons 0 x) ...)에서 일치를 시도했지만 설명서에는 (0 . x) (x은 임의 임)의 하나 이상의 요소 목록과 만 일치 함을 의미합니다. 그건 내가 원하는 것이 아니야.

리스트는 cons의 일련이므로 일치 기준을 (cons (cons 0 x) _)으로 변경하면 원하는 결과를 얻을 수 있습니다.

그 이유는 이전 시도에서 (car x) 인 이유입니다. x(list (cons 0 x) ...)에 일치하면 목록에있는 각 cons의 모든 오른쪽 요소와 일치하므로 목록을 반환했을 것입니다. 예를 들어 '((0 . 1) (0 . 2) (0 . 3))은 일치했으며 x'(1 2 3)과 같을 것입니다.

그래서, 내 고정 된 코드는 다음과 같습니다

(define (make-terminal-parser pattern) 
    (define (regexp-match-from-start pattern input) 
    (match (regexp-match-positions pattern input) 
     [(cons (cons 0 index) _) 
      (values (substring input 0 index) 
        (substring input index))] 

     [_ (error "Not found!")])) 

    (lambda (input) 
    (regexp-match-from-start pattern input))) 

N.B., 나는 또한 패턴 매칭, FWIW와 regexp-match-positions의 별표 버전을 사용할 필요가 없습니다.