2

除了小案例之外,我对整个词法分析和解析都是新手。有了这个警告,我的问题是我试图在 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[Token]对象来构造解析器。我不知道该怎么做,我也不完全理解这是否是最好的方法。

4

1 回答 1

1

听起来您可能正在混淆您的词法和句法解析器。如果您想编写自己的词法分析器,您将需要两个解析器,第一个扩展lexical.Scanners(因此提供tokentype 方法Parser[Token]),另一个扩展syntactical.TokenParsers并在其实现该特征时引用第一个抽象lexical方法。

但是,除非您有特定的理由编写自己的词法分析器,否则使用类似的东西可能更容易RegexParsers

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\"%>") 预期的那样工作。

请注意,由于我们没有编写词法分析器,因此没有义务提供Parser[Token]方法。

于 2012-05-28T00:19:07.420 回答