scala dsl parser: rep, opt и regexps - PullRequest
       16

scala dsl parser: rep, opt и regexps

2 голосов
/ 25 ноября 2010

Изучаем, как использовать scala DSL: и довольно много примеров работают хорошо.Однако я застрял на очень простой вещи:

Я анализирую язык, в котором в качестве комментария указывается '-' до конца строки.

Одна строка отлично работает, используя:

    def comment: Parser[Comment] = """--.*$""".r ^^ { case c => Comment(c) }

Но при соединении нескольких линий я получаю сообщение об ошибке.

Я пробовал несколько вариантов, но следующее кажется простым:

    def commentblock: Parser[List[Comment]] = opt(rep(comment)) ^^ {
    case Some(x) => { x }
    case None => { List() }
}

При запуске тестас двумя последовательными комментариями я получаю сообщение об ошибке.

Тестовый пример:

--Test Comment
--Test Line 2

Ошибка:

java.lang.AssertionError: Parse error: [1.1] failure: string matching regex `--.*$' expected but `-' found

Любые идеи о том, как мне следует исправитьэто?

Полный код ниже:

    import scala.util.parsing.combinator._

abstract class A
case class Comment(comment:String) extends A

object TstParser extends JavaTokenParsers {
    override def skipWhitespace = true;

    def comment: Parser[Comment] = """--.*$""".r ^^ { case c => Comment(c) }

    def commentblock: Parser[List[Comment]] = opt(rep(comment)) ^^ {
        case Some(x) => { x }
        case None => { List() }
    }

    def parse(text : String) = {
        parseAll(commentblock, text)
    }
}

class TestParser {
    import org.junit._, Assert._

    @Test def testComment() = {
        val y = Asn1Parser.parseAll(Asn1Parser.comment, "--Test Comment")
        assertTrue("Parse error: " + y, y.successful)
        val y2 = Asn1Parser.parseAll(Asn1Parser.commentblock, 
"""--Test Comment
--Test Line 2
""")
        assertTrue("Parse error: " + y2, y2.successful)
    }

}

1 Ответ

2 голосов
/ 29 ноября 2010

Не знаком со Scala, но в Java регулярное выражение --.*$ соответствует:

  • -- два дефиса;
  • .*, за которыми следуют ноль или более символов, кроме переносов строк;
  • $ с последующим концом ввода (не обязательно концом строки!).

Так что вы можете попробовать:

def comment: Parser[Comment] = """--.*""".r ^^ { case c => Comment(c) }

или даже:

def comment: Parser[Comment] = """--[^\r\n]*""".r ^^ { case c => Comment(c) }

Обратите внимание, что в обоих случаях разрыв строки остается на месте и не "используется" вашим comment "правилом".

...