2014-05-18 75 views
2

模式匹配有...做貪婪匹配(匹配0或更多),如果我想匹配的是這樣的:拍模式匹配做沒有貪婪的比賽球拍語言

#lang racket 

(define (Modifier? t) (equal? t "Modifier")) 

(define (SimpleName? t) (equal? t "SimpleName")) 

(define (SimpleType? t) (equal? t "SimpleType")) 

(define (FieldDeclaration? t) (equal? t "FieldDeclaration")) 


(match (match '("FieldDeclaration" ("Modifier") ("Modifier") ("SimpleType") ("VariableDeclarationFragment" ("SimpleName") ("StringLiteral"))) 
    [(list (? FieldDeclaration? id) (? Modifier? m) ... (? SimpleType? t) (list _ (? SimpleName? n)) _ ...) 
'yes] 

    [else 'no]) 

其打印'no,而我期望'yes。我想這由...which do a greedy matching(只是在鏈接頁面搜索「貪婪」)引起的,不過,我不太清楚這個....)

可以有0至3 ("Modifier") S IN列表,所以我該如何匹配這個表單?(實際上,還有更多的東西在功能XXX?這樣做,我必須使用的形式(? XXX? x)

PS:是否有可能extend the matching syntax這樣我就可以使用類似n_m這意味着匹配n到m次,只像{n,m}正則表達式?

回答

3

其實...不貪心,你非常接近 工作。兩個問題:

首先,你的三個謂詞是錯誤的。由於您的輸入是 ("Modifier")不是"Modifier",你想要 匹配(list "Modifier")不是"Modifier"

(define (Modifier? t) 
    (equal? t (list "Modifier"))) 

(define (SimpleName? t) 
    (equal? t (list "SimpleName"))) 

(define (SimpleType? t) 
    (equal? t (list "SimpleType"))) 

這謂語OK:

(define (FieldDeclaration? t) 
    (equal? t "FieldDeclaration")) 

其次,我看你在 模板的最後一部分放錯地方的收盤括號 - 它應該是(list _ (? SimpleName? n) _ ...)(list _ (? SimpleName? n)) _ ...

以下是全場比賽的表現,我把一些行分解,使其 更具可讀性對我說:

(match '("FieldDeclaration" 
     ("Modifier") ("Modifier") 
     ("SimpleType") 
     ("VariableDeclarationFragment" ("SimpleName") ("StringLiteral"))) 
    [(list (? FieldDeclaration? id) 
     (? Modifier? m) ... 
     (? SimpleType? t) 
     (list _ (? SimpleName? n) _ ...)) 
    'yes] 
    [_ 'no]) 

這將打印'yes

+0

許多許多非常感謝,格雷格!做得好!! –

0

格雷格寫道: 「其實...不是貪婪」,但...是貪婪如圖這些例子:

[email protected]> (match '(1 2 7 3 4 5 3 6 7 3 8) [(list a ... 3 b ...) (list a b)]) 
'((1 2 7 3 4 5 3 6 7) (8)) 

(match '(1 2 7 3 4 5 3 6 7 3 8) [(list (? number? a) ... 3 b ...) (list a b)]) 
'((1 2 7 3 4 5 3 6 7) (8)) 

我曾預計看到「((1 2 7) (4 5 3 6 7 3 8))。我遇到了匹配我想要前綴的問題,但是卻變得貪婪的行爲。