当解析表达式时,Antlr3报告java.lang.OutOfMemoryError

时间:2016-07-12 03:11:12

标签: java antlr3

我尝试匹配字符串"match 'match content'",同时提取单引号内的匹配内容。但抛出以下异常:

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
    at org.antlr.runtime.Lexer.emit(Lexer.java:160)
    at org.antlr.runtime.Lexer.nextToken(Lexer.java:91)
    at org.antlr.runtime.BufferedTokenStream.fetch(BufferedTokenStream.java:133)
    at org.antlr.runtime.BufferedTokenStream.sync(BufferedTokenStream.java:127)
    at org.antlr.runtime.CommonTokenStream.consume(CommonTokenStream.java:70)
    at org.antlr.runtime.BaseRecognizer.match(BaseRecognizer.java:106)

我不知道为什么抛出OOM异常,我找不到dot g文件中的错误定义。

我的dot g文件:

grammar Contains;

options {
    language=Java;
    output=AST;
    ASTLabelType=CommonTree;
    backtrack=false;
    k=3;
}

match
    :
    KW_MATCH SINGLE_QUOTE ( ~(SINGLE_QUOTE|'\\') | ('\\' .) )+ SINGLE_QUOTE
    ;

regexp 
    :
    KW_REGEXP SINGLE_QUOTE RegexComponent+ SINGLE_QUOTE
    ;

range 
    :
    KW_RANGE  SINGLE_QUOTE left=(LPAREN | LSQUARE) start=Number COMMA end = Number right=(RPAREN | RSQUARE) SINGLE_QUOTE
    ;


DOT : '.'; // generated as a part of Number rule
COLON : ':' ;
COMMA : ',' ;

LPAREN : '(' ;
RPAREN : ')' ;
LSQUARE : '[' ;
RSQUARE : ']' ;
LCURLY : '{';
RCURLY : '}';

PLUS : '+';
MINUS : '-';
STAR : '*';

BITWISEOR : '|';
BITWISEXOR : '^';
QUESTION : '?';
DOLLAR : '$';

KW_RANGE : 'RANGE';
KW_REGEXP : 'REGEXP';
KW_MATCH : 'MATCH';

DOUBLE_QUOTE : '\"';
SINGLE_QUOTE : '\'';

fragment
Digit
    :
    '0'..'9'
    ;

fragment
Exponent
    :
    ('e' | 'E') ( PLUS|MINUS )? (Digit)+
    ;

fragment
RegexComponent
    : 'a'..'z' | 'A'..'Z' | '0'..'9' | '_'
    | PLUS | STAR | QUESTION | MINUS | DOT
    | LPAREN | RPAREN | LSQUARE | RSQUARE | LCURLY | RCURLY
    | BITWISEXOR | BITWISEOR | DOLLAR | '\u0080'..'\u00FF' | '\u0400'..'\u04FF'
    | '\u0600'..'\u06FF' | '\u0900'..'\u09FF' | '\u4E00'..'\u9FFF' | '\u0A00'..'\u0A7F'
    ;

Number
    :
    (Digit)+ ( DOT (Digit)* (Exponent)? | Exponent)?
    ;

WS  :  (' '|'\r'|'\t'|'\n'|'\u000C')* {$channel=HIDDEN;}
    ;

1 个答案:

答案 0 :(得分:1)

您可以从更改开始:

WS  :  (' '|'\r'|'\t'|'\n'|'\u000C')* {$channel=HIDDEN;}
    ;

为:

WS  :  (' '|'\r'|'\t'|'\n'|'\u000C')+ {$channel=HIDDEN;}
    ;

你的版本匹配一个空字符串,这可能产生无限量的标记(可能会抛出一个OOME)。