scala dsl 解析器:rep、opt 和正则表达式

发布于 2024-10-04 14:09:58 字数 1656 浏览 0 评论 0原文

学习如何使用 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)
    }

}

Learning how to use scala DSL:s and quite a few examples work nice.
However I get stuck on a very simple thing:

I'm parsing a language, which has '--' as comment until end of line.

A single line works fine using:

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

But when connecting multiple lines I get an error.

I've tried several varaints, but the following feel simple:

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

When running a test with two consecutive commentlines I get an error.

Testcase:

--Test Comment
--Test Line 2

Error:

java.lang.AssertionError: Parse error: [1.1] failure: string matching regex `--.*

Any ideas on how I should fix this?

Complete code below:

    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)
    }

}

expected but `-' found

Any ideas on how I should fix this?

Complete code below:

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

他夏了夏天 2024-10-11 14:09:58

不熟悉 Scala,但在 Java 中,正则表达式 --.*$ 匹配:

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

因此,您可以尝试:

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

甚至:

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

请注意,在这两种情况下,换行符都会保留在原处,并且不会被您的注释“规则”“消耗”。

Not familiar with Scala, but in Java, the regex --.*$ matches:

  • --   two hyphens;
  • .*   followed by zero or more characters other than line breaks;
  • $     followed by the end of the input (not necessarily the end of the line!).

So you could try:

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

or even:

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

Note that in both cases, the line break is left in place and not "consumed" by your comment "rule".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文