2

私は、小さなケースを超えて、完全に字句解析と解析に慣れていません。その警告が与えられたので、私の問題は、Scala で方言のような JSP を解析しようとしていることです。char ストリームを lexing していますが、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

あなたは今、おそらく 6 つほどの問題を見つけることができるでしょう。最終的にトークン関数はパーサーを返すことになっており、これをすべて正しく理解していれば、パーサーは他のパーサーで構成できます。Parser[Token]私の考えでは、他のいくつかのオブジェクトを組み合わせてパーサーを構築できるはずです。それを行う方法がわかりません。また、それが最善の方法であるかどうかも完全にはわかりません。

4

1 に答える 1

1

字句パーサーとシナクティックパーサーを混同しているようです。独自のレクサーを作成するルートをたどる場合は、2つのパーサーが必要です。最初のパーサーは拡張されlexical.Scanners(したがってtoken、タイプのメソッドを提供しますParser[Token])、もうsyntactical.TokenParsers1つは、その特性の実装で最初のパーサーを拡張して参照します。抽象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 に答える