Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Advanced control of recursive parser in scala

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

This recursive parser will try to parse "(?ui)(regexvalue)".r until the end of input. Is in scala a way to prohibit parsing when some defined number of characters were consumed by "uninterestingthings" ?

UPD: I have one poor solution:

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 => 
      }
  }
}

Disadvantages:
- not all members are lazy vals so PackratParser will have some time penalty
- constructing regexps on every "uninteresting" method call - time penalty
- using exception to control program - code style and time penalty

like image 950
Jeriho Avatar asked Oct 25 '22 15:10

Jeriho


1 Answers

The quick-n-dirty answer is to just limit the number of characters in your regex for uninterestingthings and make it not recursive:

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

Based on the comment about greediness eating the regexvalue, I propose a single regex:

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

But we seem to have ventured outside the realm of scala parsers into regex minutia. I'd be interested in seeing other results.

like image 185
Mitch Blevins Avatar answered Nov 11 '22 10:11

Mitch Blevins