【问题标题】:Combining parsers when lexing an SGMLish document in Scala在 Scala 中对 SGMLish 文档进行词法分析时组合解析器
【发布时间】:2012-05-27 18:46:44
【问题描述】:

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

【问题讨论】:

    标签: scala parsing lexical-analysis scala-2.9


    【解决方案1】:

    听起来您可能混淆了词法和句法解析器。如果您想编写自己的词法分析器,则需要两个解析器,第一个扩展 lexical.Scanners(因此提供 Parser[Token] 类型的 token 方法),另一个扩展 @987654325 @ 并在其实现该特征的抽象 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, "&lt;%tag attribute=\"value\"%&gt;") 这样的东西可以按预期工作。

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

    【讨论】:

    • 太棒了!是的,我想我可能把事情搞混了。我的第一个挑战是 RegexParsers 吃掉了空白,这在某些情况下很重要,比如生成一个重要的空间输出文件的 JSP,然后我发现了 skipWhitespace,在上面的这个例子中,我已经很好地工作了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 2020-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多