Я построил грамматику «простых», чтобы интерпретировать файл, похожий на json (или xml). Но, когда я пытаюсь разобрать файл и перемещаться по дереву, я получаю System.OutOfMemoryException
.Почему я получаю OutOfMemoryException при генерации дерева парсеров с ANTLR?
Входной файл имеет только 108 МБ, но содержит почти 5 миллионов строк.
Вот пример файла:
(
:field ("ObjectName"
:field (
:field ("{6BF621F9-A0E2-49BB-A86B-3DE4750954F4}")
:field (Value)
:field (Value)
:field (
:Time ("Sun Jan 26 10:08:33 2014")
:last_modified_utc (1390730913)
:By ("Some text")
:From (localhost)
)
:field ("text/text")
:field (false)
:field (false)
)
:field()
:field()
:field()
:field (0)
:field (true)
:field (true)
)
.
.
.
.
.
)
После грамматики:
grammar Objects;
/*
* Parser Rules
*/
compileUnit
: obj
;
obj
: OPEN ID? (field)* CLOSE
;
field
: ':'(ID)? obj
;
/*
* Lexer Rules
*/
OPEN
: '('
;
CLOSE
: ')'
;
ID
: (ALPHA | ALPHA_IN_STRING)
;
fragment
INT_ID
: ('0'..'9')
;
fragment
ALPHA_EACH
: 'A'..'Z' | 'a'..'z' | '_' | INT_ID | '-' | '.' | '@'
;
fragment
ALPHA
: (ALPHA_EACH)+
;
fragment
ALPHA_IN_STRING
: ('"' (~[\r\n])+ '"')
;
WS
// : ' ' -> channel(HIDDEN)
: [ \t\r\n]+ -> skip // skip spaces, tabs, newlines
;
И парсера:
var input = new Antlr4.Runtime.AntlrInputStream(text);
var lexer = new ObjectsLexer(input);
var tokens = new Antlr4.Runtime.CommonTokenStream(lexer);
var parser = new ObjectsParser(tokens);
// Context for the compileUnit rule
// ERROR: Here I got the error. When start the to build the tree for compileUnit rule
var ctx = parser.compileUnit();
// The following line is not executed
new ObjectsVisitor().Visit(ctx);
На линии ошибок, я понимаю, что рост экспоненциальности.
Если бы у меня был большой XML-файл, похожий на 5 миллионов строк, ANTLR не лучший инструмент для чтения/интерпретации, не так ли? В этом случае, должен ли я сделать что-то часть, без ANTLR? – anmaia
Любой способ очистки кеша? Я знаю, что это не идеально, но нехватка памяти тоже не идеальна :-( –