2012-10-31 7 views
5

क्या स्कैला पार्सर संयोजकों के साथ मैचों को उलटा करना संभव है? मैं एक पार्सर के साथ लाइनों से मिलान करने की कोशिश कर रहा हूं जो कीवर्ड के एक सेट से शुरू नहीं करते हैं। मैं इसे एक कष्टप्रद शून्य चौड़ाई नकारात्मक लुकहेड नियमित अभिव्यक्ति (उदा। "(?!h1|h2).*") के साथ कर सकता हूं, लेकिन मैं इसे स्कैला पार्सर के साथ करना चाहूंगा। सबसे अच्छा मैं इसके साथ आने में सक्षम हूं:स्कैला पार्सर-संयोजक: मैचों को कैसे बदला जाए?

def keyword = "h1." | "h2." 
def alwaysfails = "(?=a)b".r 
def linenotstartingwithkeyword = keyword ~! alwaysfails | ".*".r 

विचार यहां है कि मैं ~ का उपयोग करता हूं! सभी मिलान करने वाले regexp पर बैकट्रैकिंग को रोकने के लिए, और उसके बाद एक regex "(? = a) b" .r के साथ जारी रखें जो कुछ भी मेल नहीं खाता है। (वैसे, क्या कोई पूर्वनिर्धारित पार्सर है जो हमेशा विफल रहता है?) यदि कोई कीवर्ड पाया जाता है तो लाइन मिलान नहीं की जाएगी, लेकिन यदि मिलान मेल नहीं खाता है तो मिलान किया जाएगा।

मुझे आश्चर्य है कि ऐसा करने का एक बेहतर तरीका है या नहीं। है?

उत्तर

6

आप not यहाँ का उपयोग कर सकते हैं:

import scala.util.parsing.combinator._ 

object MyParser extends RegexParsers { 
    val keyword = "h1." | "h2." 
    val lineNotStartingWithKeyword = not(keyword) ~> ".*".r 

    def apply(s: String) = parseAll(lineNotStartingWithKeyword, s) 
} 

अब:

scala> MyParser("h1. test") 
res0: MyParser.ParseResult[String] = 
[1.1] failure: Expected failure 

h1. test 
^ 

scala> MyParser("h1 test") 
res1: MyParser.ParseResult[String] = [1.8] parsed: h1 test 

नोट वहाँ भी Parsers पर एक failure तरीका है कि है, तो आप बस के रूप में अच्छी तरह से keyword ~! failure("keyword!") के साथ अपने संस्करण लिखा जा सकता था। लेकिन not बहुत अच्छा है, वैसे भी।

संबंधित मुद्दे