2012-11-03 15 views
13

ho scritto un parser come segue:Scala parser combinatore, grande problema di file

class LogParser extends JavaTokenParsers { 

    def invertedIndex: Parser[Array[Array[(Int, Int)]]] = { 
    num ~> num ~> num ~> rep(postingsList) ^^ { 
     _.toArray 
    } 
    } 

    def postingsList: Parser[Array[(Int, Int)]] = { 
    num ~> rep(entry) ^^ { 
     _.toArray 
    } 
    } 

    def entry = { 
    num ~ "," ~ num ^^ { 
     case docID ~ "," ~ count => (docID.toInt, count.toInt) 
    } 
    } 

    def num = wholeNumber ^^ (_.toInt) 

} 

Se mi parse da un (270MB) di file con un FileReader come segue:

val index = parseAll(invertedIndex, new FileReader("path/to/file")).get 

ottengo un Exception in thread "main" java.lang.StackOverflowError (ho anche provato avvolgendoli in un BufferedReader), ma posso risolvere il problema dalla prima lettura il file in una stringa in questo modo:

val input = io.Source.fromFile("path/to/file") 
val str = input.mkString 
input.close() 
val index = parseAll(invertedIndex, str).get 

Perché è così? C'è un modo per evitare di leggerlo prima come una stringa, sembra uno spreco?

+2

Qual è la dimensione attuale del tuo stack, e quanto più grande si fa a fare per rendere il vostro stack per evitare la StackOverflowException? Quanto più piccolo deve essere lo stack per rendere l'overflow della versione String? (Puoi impostare lo stack su 16 MB avviando in questo modo: 'scala -J-Xss16M') – DaoWen

+0

Stavo solo usando la dimensione dello stack predefinita, ma quando l'ho impostato su 16M il programma era ancora in esecuzione 30 minuti dopo ... – Robert

+1

Questo potrebbe essere correlato al bug di Scala 2.9.2 [SI-6520] (https://issues.scala-lang.org/browse/SI-6520). –

risposta

1

C'è un'altra libreria [1] che è molto simile ai combinatori di parser scala che supporta Trampolining, che è ciò che è necessario per arrestare gli errori di stackoverflow.

[1] https://github.com/djspiewak/gll-combinators

Problemi correlati