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は任意です)の1つ以上の要素のリストにのみ一致することを示しています。それは私が望むものではありません。

リストは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のスターを付けたバージョンを使用する必要はありません。

関連する問題