gpt4 book ai didi

scala - 如何忽略解析器组合器中的单行注释

转载 作者:行者123 更新时间:2023-12-04 18:42:59 25 4
gpt4 key购买 nike

我有一个可用的解析器,但我刚刚意识到我不接受评论。在我正在解析的 DSL 中,注释以 ; 开头。特点。如果 ;遇到了,休息 该行的被忽略(但不是全部,除非第一个字符是 ; )。

我在延长 RegexParsers对于我的解析器并忽略空格(默认方式),所以无论如何我都会丢失换行符。我也不希望修改每个解析器来满足注释的可能性,因为语句可以跨越多行(因此每个语句的每个部分都可能以注释结尾)。有没有干净的方法来实现这一目标?

最佳答案

可能影响您选择的一件事是是否可以在您的有效解析器中找到注释。例如,假设您有以下内容:

val p = "(" ~> "[a-z]*".r <~ ")"

它将解析类似 ( abc ) 的内容但由于评论,您实际上可能会遇到以下情况:
( ; comment goes here
abc
)

然后我建议使用 TokenParser或其子类之一。这是更多的工作,因为您必须提供一个词法解析器,该解析器将执行第一遍以丢弃注释。但是,如果您有嵌套的注释或 ;,它也更灵活。可以转义或者如果 ;可以在字符串文字中,例如:
abc = "; don't ignore this" ; ignore this

另一方面,您也可以尝试覆盖 whitespace 的值。像
override protected val whiteSpace = """(\s|;.*)+""".r

或类似的规定。
例如使用 RegexParsers scaladoc 中的示例:
import scala.util.parsing.combinator.RegexParsers

object so1 {
Calculator("""(1 + ; foo
(1 + 2))
; bar""")
}

object Calculator extends RegexParsers {
override protected val whiteSpace = """(\s|;.*)+""".r
def number: Parser[Double] = """\d+(\.\d*)?""".r ^^ { _.toDouble }
def factor: Parser[Double] = number | "(" ~> expr <~ ")"
def term: Parser[Double] = factor ~ rep("*" ~ factor | "/" ~ factor) ^^ {
case number ~ list => (number /: list) {
case (x, "*" ~ y) => x * y
case (x, "/" ~ y) => x / y
}
}
def expr: Parser[Double] = term ~ rep("+" ~ log(term)("Plus term") | "-" ~ log(term)("Minus term")) ^^ {
case number ~ list => list.foldLeft(number) { // same as before, using alternate name for /:
case (x, "+" ~ y) => x + y
case (x, "-" ~ y) => x - y
}
}
def apply(input: String): Double = parseAll(expr, input) match {
case Success(result, _) => result
case failure: NoSuccess => scala.sys.error(failure.msg)
}
}

这打印:
Plus term --> [2.9] parsed: 2.0
Plus term --> [2.10] parsed: 3.0
res0: Double = 4.0

关于scala - 如何忽略解析器组合器中的单行注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20925434/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com