2010-05-12 19 views
5
val uninterestingthings = ".".r 
val parser = "(?ui)(regexvalue)".r | (uninterestingthings~>parser) 

Trình phân tích cú pháp đệ quy này sẽ cố gắng phân tích cú pháp "(? Ui) (regexvalue)". R cho đến khi kết thúc đầu vào. Là trong scala một cách để ngăn chặn phân tích cú pháp khi một số xác định số ký tự đã được tiêu thụ bởi "uninterestingthings"?Kiểm soát nâng cao trình phân tích đệ quy trong scala

UPD: Tôi có một giải pháp nghèo:

object NonRecursiveParser extends RegexParsers with PackratParsers{ 
    var max = -1 
    val maxInput2Consume = 25 
    def uninteresting:Regex ={ 
    if(max<maxInput2Consume){ 
    max+=1 
    ("."+"{0,"+max.toString+"}").r 
    }else{ 
     throw new Exception("I am tired") 
    } 
    } 
    lazy val value = "itt".r 
    def parser:Parser[Any] = (uninteresting~>value)|parser 
    def parseQuery(input:String) = { 
     try{ 
     parse(parser, input) 
     }catch{ 
      case e:Exception => 
     } 
    } 
} 

Nhược điểm:
- không phải tất cả các thành viên là Vals lười biếng vì vậy PackratParser sẽ có một thời gian hình phạt
- xây dựng regexps trên mỗi "không thú vị" phương pháp gọi - hình phạt thời gian
- sử dụng ngoại lệ để kiểm soát kiểu chương trình - mã và hình phạt thời gian

+0

Bạn sẽ giải quyết vấn đề này như thế nào với các thư viện, trình tạo hoặc khung công cụ phân tích cú pháp khác? –

+0

Bạn đang thực sự cố gắng làm gì? –

Trả lời

3

Câu trả lời nhanh chóng là chỉ giới hạn số lượng ký tự trong regex của bạn cho những điều không thú vị và làm cho nó không đệ quy:

val uninterestingthings = ".{0,60}".r // 60-chars max 
val parser = (uninterestingthings~>"(?ui)(regexvalue)".r)* 

Dựa trên những nhận xét về sự tham lam ăn regexvalue, tôi đề xuất một regex duy nhất:

val parser = ("(?.{0,60}?)(?ui)(regexvalue)".r)* 

Nhưng chúng ta dường như đã mạo hiểm bên ngoài lĩnh vực của scala trình phân tích cú pháp thành regex minutia. Tôi muốn được nhìn thấy kết quả khác.

+0

Nó sẽ không hoạt động vì "uninterestingthings" là tham lam và sẽ luôn luôn tiêu thụ 60 ký tự đầu vào – Jeriho

0

Sử dụng trình thông báo để phá vỡ mọi thứ trước tiên, sử dụng tất cả các regexps cho những điều thú vị mà bạn đã biết. Sử dụng một số ".".r để đối sánh những điều không thú vị nếu chúng quan trọng đối với ngữ pháp của bạn. (Hoặc vứt chúng đi nếu chúng không quan trọng đối với ngữ pháp.) Những điều thú vị của bạn bây giờ có các kiểu đã biết, và chúng được nhận diện bởi trình mã thông báo bằng cách sử dụng một thuật toán khác với phân tích cú pháp. Vì tất cả các vấn đề về lookahead được giải mã bởi trình mã thông báo, trình phân tích cú pháp phải dễ dàng.

Các vấn đề liên quan