scala解析器组合器中的eol识别
我正在尝试使用解析器组合器来创建一个非常简单的解析器(解析类似于BNF的东西)。我查看了几篇解释这一问题的博客文章(谷歌排名靠前的文章(对我来说)),我想我能理解,但测试表明情况并非如此 我已经检查了StackOverflow中的问题,虽然有些问题可能会在我尝试应用它们时得到应用和有用,但其他问题会出现,所以最好的方法是通过一个具体的示例: 这是我的主要观点:scala解析器组合器中的eol识别,scala,parsing,parser-combinators,eol,Scala,Parsing,Parser Combinators,Eol,我正在尝试使用解析器组合器来创建一个非常简单的解析器(解析类似于BNF的东西)。我查看了几篇解释这一问题的博客文章(谷歌排名靠前的文章(对我来说)),我想我能理解,但测试表明情况并非如此 我已经检查了StackOverflow中的问题,虽然有些问题可能会在我尝试应用它们时得到应用和有用,但其他问题会出现,所以最好的方法是通过一个具体的示例: 这是我的主要观点: def main(args: Array[String]) { val parser: BaseParser = new Bas
def main(args: Array[String]) {
val parser: BaseParser = new BaseParser
val eol = sys.props("line.separator")
val test = s"a = b ${eol} a = c ${eol}"
System.out.println(test)
parser.parse(test)
}
这是解析器:
import com.github.trylks.tests.parser.ParserClasses._
import scala.util.parsing.combinator.syntactical._
import scala.util.parsing.combinator.ImplicitConversions
import scala.util.parsing.combinator.PackratParsers
class BaseParser extends StandardTokenParsers with ImplicitConversions with PackratParsers {
val eol = sys.props("line.separator")
lexical.delimiters += ("=", "|", "*", "[", "]", "(", ")", ";", eol)
def rules = rep1sep(rule, eol) ^^ { Rules(_) }
def rule = id ~ "=" ~ repsep(expression, "|") ^^ flatten3 { (e1: ID, _: Any, e3: List[Expression]) => Rule(e1, e3) }
def expression: Parser[Expression] = (element | parenthesized | optional) ^^ { x => x } // and sequence and repetition, but that's another problem...
def parenthesized: Parser[Expression] = "(" ~> expression <~ ")" ^^ { x => x }
def optional: Parser[Expression] = "[" ~> expression <~ "]" ^^ { Optional(_) }
def element: Parser[Element] = (id | constant) ^^ { x => x }
def constant: Parser[Constant] = stringLit ^^ { Constant(_) }
def id: Parser[ID] = ident ^^ { ID(_) }
def parse(text: String): Option[Rules] = {
val s = rules(new lexical.Scanner(text))
s match {
case Success(res, next) => {
println("Success!\n" + res.toString)
Some(res)
}
case Error(msg, next) => {
println("error: " + msg)
None
}
case Failure(msg, next) => {
println("failure: " + msg)
None
}
}
}
}
问题是:现在的代码不起作用,它只解析一条规则(不是两条)。如果我将eol
替换为“;”
(在main和解析器中),那么它可以工作(至少对于这个测试是这样的)
大多数人似乎更喜欢正则表达式解析器,每个解释解析器组合器的博客都没有详细介绍可以扩展或不扩展的特性,所以我不知道这些差异或者为什么会有几个差异(我这么说是因为理解代码为什么不起作用可能很重要)。问题是:如果我尝试使用正则表达式解析器,那么我在解析器
“=”
,“*”
,等等中指定的所有字符串都会出错。我认为这已经解决了。我无法使用StandardTokenParsers
执行此操作。我切换到RegexParsers
,并且我覆盖def
中的whitespace
。我没有犯以前犯过的错误(我生活在混乱中),现在一切似乎都正常了。我将id
定义为“\w+”.r
并将常量定义为“\”(\\.\124;【^】)*\”.r
(我不知道为什么我有这么多引号…)。我可能在将来的某个时候继续。
object ParserClasses {
abstract class Element extends Expression
case class ID(value: String) extends Element {
override def toString(): String = value
}
case class Constant(value: String) extends Element {
override def toString(): String = value
}
abstract class Expression
case class Optional(value: Expression) extends Expression {
override def toString() = s"[$value]"
}
case class Rule(head: ID, body: List[Expression]) {
override def toString() = s"$head = ${body.mkString(" | ")}"
}
case class Rules(rules: List[Rule]) {
override def toString() = rules.mkString("\n")
}
}