代码之家  ›  专栏  ›  技术社区  ›  Bjorn J

scala dsl解析器:rep、opt和regexps

  •  2
  • Bjorn J  · 技术社区  · 15 年前

    学习如何使用scala DSL:s和许多示例都很好。 然而,我被一件非常简单的事情困住了:

    我正在分析一种语言,该语言在行尾之前都有“--”作为注释。

    一条线可以很好地使用:

        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 回复  |  直到 15 年前
        1
  •  2
  •   Bart Kiers    15 年前

    不熟悉Scala,但在Java中,regex --.*$ 比赛:

    • -- 两个连字符;
    • .* 后跟除换行符以外的零个或多个字符;
    • $ 后跟输入的结尾(不一定是行的结尾!).

    所以你可以尝试:

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

    甚至:

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

    注意,在这两种情况下,换行符都保留在原位,而不是由 comment “规则”。

    推荐文章