5
val uninterestingthings = ".".r
val parser = "(?ui)(regexvalue)".r | (uninterestingthings~>parser)

この再帰パーサーは、入力の最後まで "(?ui)(regexvalue)".r を解析しようとします。定義された数の文字が「uninterestingthings」によって消費されたときに解析を禁止する方法はscalaにありますか?

UPD:私は1つの悪い解決策を持っています:

object NonRecursiveParser extends RegexParsers with PackratParsers{
  var max = -1
  val maxInput2Consume = 25
  def uninteresting:Regex ={
    if(max<maxInput2Consume){
    max+=1
    ("."+"{0,"+max.toString+"}").r
    }else{
      throw new Exception("I am tired")
    }
  }
  lazy val value = "itt".r
  def parser:Parser[Any] = (uninteresting~>value)|parser
  def parseQuery(input:String) = {
      try{
      parse(parser, input)
      }catch{
          case e:Exception => 
      }
  }
}

欠点:
- すべてのメンバーが遅延 val であるとは限らないため、PackratParser には時間のペナルティがあり
ます

4

2 に答える 2

3

素早い答えは、興味のないもののために正規表現の文字数を制限し、再帰的でないようにすることです。

val uninterestingthings = ".{0,60}".r  // 60-chars max
val parser = (uninterestingthings~>"(?ui)(regexvalue)".r)*

正規表現を食べる貪欲についてのコメントに基づいて、私は単一の正規表現を提案します:

val parser = ("(?.{0,60}?)(?ui)(regexvalue)".r)*

しかし、私たちはスカラパーサーの領域の外で正規表現の特徴に挑戦したようです。他の結果を見たいと思います。

于 2010-05-12T13:29:26.767 に答える
0

トークナイザーを使用して最初に物事を分割し、すべての正規表現を使用して、既に知っている興味深いものにします。文法にとって重要な場合は、興味のないものと一致させるために single".".rを使用します。(または、文法にとって重要でない場合は破棄してください。) 興味深いものには既知の型があり、解析とは異なるアルゴリズムを使用してトークナイザーによって識別されます。先読み問題はすべてトークナイザーによって解決されるため、パーサーは簡単なはずです。

于 2010-05-24T00:58:45.930 に答える