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

此递归解析器将尝试解析 "(?ui)(regexvalue)".r 直到输入结束。当某些定义数量的字符被“无趣的东西”消耗时,scala 是否有一种禁止解析的方法?

UPD:我有一个糟糕的解决方案:

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

quick-n-dirty 的答案是只限制正则表达式中无趣的字符数,并使其不递归:

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

基于关于贪婪吃正则表达式的评论,我提出了一个单一的正则表达式:

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

但是我们似乎已经冒险走出了 scala 解析器的领域,进入了正则表达式的细节。我有兴趣看到其他结果。

于 2010-05-12T13:29:26.767 回答
0

首先使用标记器分解事物,将所有正则表达式用于您已经知道的有趣事物。".".r如果它们对您的语法很重要,请使用单个来匹配无趣的事物。(或者如果它们对语法不重要,则将它们丢弃。)您有趣的事物现在具有已知类型,并且它们由标记器使用与解析不同的算法来识别。由于所有前瞻问题都由分词器解决,因此解析器应该很容易。

于 2010-05-24T00:58:45.930 回答