在Scala中复制SGMLish文档时组合解析器

时间:2012-05-27 18:46:44

标签: scala parsing lexical-analysis scala-2.9

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

1 个答案:

答案 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\"%>")方法。