7

私はパーサー コンビネータを試していますが、無限再帰のように見えることがよくあります。これが私が最初に遭遇したものです:

import util.parsing.combinator.Parsers
import util.parsing.input.CharSequenceReader

class CombinatorParserTest extends Parsers {

  type Elem = Char

  def notComma = elem("not comma", _ != ',')

  def notEndLine = elem("not end line", x => x != '\r' && x != '\n')

  def text = rep(notComma | notEndLine)

}

object CombinatorParserTest {

  def main(args:Array[String]): Unit = {
    val p = new CombinatorParserTest()
    val r = p.text(new CharSequenceReader(","))
    // does not get here
    println(r)
  }

}

何が起こっているのかを印刷するにはどうすればよいですか? そして、なぜこれは終わらないのですか?

4

3 に答える 3

4

解析の試行をログに記録し、繰り返し解析されnotCommanotEndLineいるのがファイルの終わり (log(...)("mesg") 出力で CTRL-Z として表示) であることを示します。この目的のためにパーサーをどのように変更したかを次に示します。

def text = rep(log(notComma)("notComma") | log(notEndLine)("notEndLine"))

何が起こっているのか完全にはわかりません (あなたの文法で多くのバリエーションを試しました) が、次のようなものだと思います: EOF は実際には入力ストリームに人為的に導入された文字ではなく、入力の終わり。したがって、この決して消費されない EOF 疑似文字は、「カンマでも行末でもない」として繰り返し解析されます。

于 2010-03-05T16:53:30.617 に答える
2

わかりました、私はこれを理解したと思います。`CharSequenceReader は、入力の終わりのマーカーとして '\032' を返します。したがって、入力を次のように変更すると、機能します。

import util.parsing.combinator.Parsers
import util.parsing.input.CharSequenceReader

class CombinatorParserTest extends Parsers {

  type Elem = Char

  import CharSequenceReader.EofCh

  def notComma = elem("not comma", x => x != ',' && x!=EofCh)

  def notEndLine = elem("not end line", x => x != '\r' && x != '\n' && x!=EofCh)

  //def text = rep(notComma | notEndLine)
  def text = rep(log(notComma)("notComma") | log(notEndLine)("notEndLine"))

}

object CombinatorParserTest {

  def main(args:Array[String]): Unit = {
    val p = new CombinatorParserTest()
    val r = p.text(new CharSequenceReader(","))
    println(r)
  }

}

CharSequenceReader ここのソースコードを参照してください。スカドックがそれについて言及していれば、私は多くの時間を節約できたでしょう.

于 2010-03-06T02:10:13.517 に答える