Tôi đã viết một phân tích cú pháp như sau:Scala phân tích cú pháp Combinator, tập tin lớn vấn đề
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)
}
Nếu tôi phân tích từ một (270MB) tập tin với một FileReader như sau:
val index = parseAll(invertedIndex, new FileReader("path/to/file")).get
tôi nhận được một Exception in thread "main" java.lang.StackOverflowError
(Tôi cũng đã thử gói trong một BufferedReader
) nhưng tôi có thể sửa chữa nó bằng cách đầu tiên đọc tệp vào một Chuỗi như vậy:
val input = io.Source.fromFile("path/to/file")
val str = input.mkString
input.close()
val index = parseAll(invertedIndex, str).get
Tại sao lại xảy ra trường hợp này? Có cách nào để tránh đọc nó như là một String đầu tiên, nó có vẻ như một sự lãng phí?
kích thước hiện tại của chồng của bạn là gì, và làm thế nào lớn hơn nhiêu bạn phải chắc chồng của bạn để tránh StackOverflowException? Ngăn xếp phải nhỏ hơn bao nhiêu để làm cho tràn phiên bản String? (Bạn có thể đặt ngăn xếp thành 16MB bằng cách khởi chạy như vậy: 'scala -J-Xss16M') – DaoWen
Tôi chỉ sử dụng kích thước ngăn xếp mặc định, nhưng khi tôi đặt thành 16M thì chương trình vẫn chạy 30 phút sau ... – Robert
có thể liên quan đến lỗi Scala 2.9.2 [SI-6520] (https://issues.scala-lang.org/browse/SI-6520). –