2010-05-12 1 views
5
val uninterestingthings = ".".r 
val parser = "(?ui)(regexvalue)".r | (uninterestingthings~>parser) 

Этот рекурсивный синтаксический анализатор попытается разобрать «(? Ui) (regexvalue)». R до конца ввода. Есть ли в scala способ запретить синтаксический анализ, когда определенное количество символов было уничтожено «неинтересными»?Расширенный контроль рекурсивного анализатора в 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 => 
     } 
    } 
} 

Недостатки:
- не все члены ленивые Vals так PackratParser будет иметь какое-то время штраф
- строительство регэкспы на каждом «неинтересной» вызов метода - штраф времени
- с использованием исключения для программы управления - стиль кода и штраф времени

+0

Как бы вы решили эту проблему с другими библиотеками-анализаторами, генераторами или фреймворками? –

+0

Что вы на самом деле пытаетесь сделать? –

ответ

3

Быстрый-грязный ответ заключается в том, чтобы просто ограничить количество символов в вашем регулярном выражении для неинтересных действий и сделать это не рекурсивным:

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

Основываясь на комментарий о жадности поедая regexvalue, я предлагаю один регулярное выражение:

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

Но мы, кажется, отважились вне сферы Скале парсеры в регулярные выражения. Мне бы хотелось увидеть другие результаты.

+0

Это не сработает, потому что «неинтересные» жадные и всегда будут потреблять 60 символов ввода – Jeriho

0

Используйте токенизатор, чтобы сначала разбить вещи, используя все регулярные выражения для интересных вещей, которые вы уже знаете. Используйте один ".".r, чтобы соответствовать неинтересным вещам, если они важны для вашей грамматики. (Или выбросьте их, если они не важны для грамматики.) Ваши интересные вещи теперь известны типам, и они идентифицируются токенизатором с использованием другого алгоритма, чем разбор. Поскольку все проблемы с обзором решаются токенизатором, парсер должен быть простым.