我是新手,在整个小案例之外进行整理和解析。有了这个警告,我的问题是我试图在Scala中解析像方言这样的JSP。我正在使用char流,当我找到类似JSP的标签时,我就卡住了。
Some text<%tag attribute="value"%>more stuff.
我的词法分析员现在试图拉出标记部分并进行标记化,所以我有类似的东西:
def document: Parser[Token] = tag | regular
def tag: Parser[Token] = elem('<') ~ elem('%') ~ rep1(validTagName) ~ tagAttribute.* ~ elem('%') ~ elem('>') ^^ {
case a ~ b ~ tagName ~ tagAttributes ~ c ~ d => {
Tag(tagName.foldLeft("")(_+_)) :: tagAttributes.flatMap(_)
}
}
def validTagName: Parser[Token] = elem("",Character.isLetter(_)) // over-simplified
... Other code for tagAttribute and Tag extends Token here
你现在可能已经发现了大约六个问题,我知道我自己可以发现一些问题,但是,这就是我现在所处的位置。最终,令牌函数应该返回一个Parser,如果我理解这一切,Parser可以由其他解析器组成。我的想法是,我应该能够通过组合其他几个Parser[Token]
对象来构造一个解析器。我不知道该怎么做,如果这是最好的方法,我不完全理解。
答案 0 :(得分:1)
听起来你可能正在混淆你的词法和同义词解析器。如果你想要编写自己的词法分析器的路线,你需要两个解析器,第一个扩展lexical.Scanners
(因此提供类型为token
的{{1}}方法),以及另一个扩展Parser[Token]
并引用该特征的抽象syntactical.TokenParsers
方法实现的第一个。
除非你有一些特定的理由来编写自己的词法分析器,否则使用RegexParsers
之类的东西会更容易:
lexical
现在import scala.util.parsing.combinator._
object MyParser extends RegexParsers {
def name = "\\p{Alpha}+".r
def value = "\"" ~> "[^\"]*".r <~ "\""
def attr = name ~ "=" ~ value ^^ { case k ~ _ ~ v => k -> v }
def tag: Parser[(String, Map[String, String])] =
"<%" ~> name ~ rep(attr) <~ "%>" ^^ {
case tagName ~ attrs => tagName -> attrs.toMap
}
}
之类的工作正常。
请注意,由于我们没有编写词法分析器,因此没有义务提供MyParser.parseAll(MyParser.tag, "<%tag attribute=\"value\"%>")
方法。