Jer*_*iho 5 parsing scala parser-combinators
val uninterestingthings = ".".r
val parser = "(?ui)(regexvalue)".r | (uninterestingthings~>parser)
Run Code Online (Sandbox Code Playgroud)
这个递归解析器将尝试解析"(?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 =>
}
}
}
Run Code Online (Sandbox Code Playgroud)
缺点:
- 并非所有成员都是懒惰的,所以PackratParser会有一些时间惩罚
- 在每个"无趣的"方法调用上构建正则表达式- 时间惩罚
- 使用异常来控制程序 - 代码风格和时间惩罚
快速而肮脏的答案是仅限制正则表达式中无趣事物的字符数并使其不递归:
val uninterestingthings = ".{0,60}".r // 60-chars max
val parser = (uninterestingthings~>"(?ui)(regexvalue)".r)*
Run Code Online (Sandbox Code Playgroud)
根据关于贪婪吞噬正则表达式值的评论,我提出了一个正则表达式:
val parser = ("(?.{0,60}?)(?ui)(regexvalue)".r)*
Run Code Online (Sandbox Code Playgroud)
但我们似乎已经走出了 scala 解析器的领域,进入了正则表达式的细节领域。我有兴趣看到其他结果。