ANTLR4 java .lang.StackOverflowError - PullRequest
       32

ANTLR4 java .lang.StackOverflowError

2 голосов
/ 05 августа 2020

Я новичок в Antlr4, я написал простой файл грамматики, который успешно компилируется, но выдает исключение Stackoverflow, когда я пытаюсь проверить образец ввода.

Файл грамматики:

grammar SampleGrammar;

options {
  language = Java;
}

expression : (c1=someName|a1=attrName) OP literal       #clauseOperation
        ;
       
someName: MY;
attrName : (attribute '.')any_name;
attribute : ATTRIBUTE;
any_name : IDENT;
literal : NULL | INTEGER | NUMBER | TRUE | FALSE | STRING;


ATTRIBUTE : A T T R I B U T E;
OP : '=' | '!=';

MY : M Y;
WS : (' ' | '\t' | '\n' | '\r' | '\f')+ -> skip;
NULL : N U L L;
TRUE : T R U E;
FALSE : F A L S E;
INTEGER : '-'? [0-9]+;
NUMBER : '-'? [0-9]* ( '.' [0-9]+);
STRING : '\'' (ESC|.)*? '\'';
IDENT : [a-zA-Z][a-zA-Z0-9-_]*;


fragment A : 'A' | 'a' ;
fragment B : 'B' | 'b' ;
fragment C : 'C' | 'c' ;
fragment D : 'D' | 'd' ;
fragment E : 'E' | 'e' ;
fragment F : 'F' | 'f' ;
fragment G : 'G' | 'g' ;
fragment H : 'H' | 'h' ;
fragment I : 'I' | 'i' ;
fragment J : 'J' | 'j' ;
fragment K : 'K' | 'k' ;
fragment L : 'L' | 'l' ;
fragment M : 'M' | 'm' ;
fragment N : 'N' | 'n' ;
fragment O : 'O' | 'o' ;
fragment P : 'P' | 'p' ;
fragment Q : 'Q' | 'q' ;
fragment R : 'R' | 'r' ;
fragment S : 'S' | 's' ;
fragment T : 'T' | 't' ;
fragment U : 'U' | 'u' ;
fragment V : 'V' | 'v' ;
fragment W : 'W' | 'w' ;
fragment X : 'X' | 'x' ;
fragment Y : 'Y' | 'y' ;
fragment Z : 'Z' | 'z' ;
fragment ESC : '\\\'' | '\\\\';

Тестовый ввод:

Он всегда вызывает исключение StackOverFlowException. Я выполнил следующие шаги:

export CLASSPATH=".:/c/work/antlr/antlr4-4.8-1-complete.jar:$CLASSPATH"
alias antlr4='java -Xmx4g -cp "/c/work/antlr/antlr4-4.8-1-complete.jar:$CLASSPATH" org.antlr.v4.Tool'
alias grun='java org.antlr.v4.gui.TestRig'
antlr4 SampleGrammar.g4 
javac SampleGrammar*.java
grun SampleGrammar expression input.txt -gui

input.txt: MY = "MyName"

throws:

Exception in thread "main" java.lang.StackOverflowError
        at org.antlr.v4.runtime.misc.MurmurHash.update(MurmurHash.java:71)
        at org.antlr.v4.runtime.atn.LexerATNConfig.hashCode(LexerATNConfig.java:78)
        at org.antlr.v4.runtime.misc.ObjectEqualityComparator.hashCode(ObjectEqualityComparator.java:29)
        at org.antlr.v4.runtime.misc.Array2DHashSet.getBucket(Array2DHashSet.java:108)
        at org.antlr.v4.runtime.misc.Array2DHashSet.getOrAddImpl(Array2DHashSet.java:63)
        at org.antlr.v4.runtime.misc.Array2DHashSet.getOrAdd(Array2DHashSet.java:59)
        at org.antlr.v4.runtime.atn.ATNConfigSet.add(ATNConfigSet.java:146)
        at org.antlr.v4.runtime.atn.ATNConfigSet.add(ATNConfigSet.java:122)
        at org.antlr.v4.runtime.atn.LexerATNSimulator.closure(LexerATNSimulator.java:446)
        at org.antlr.v4.runtime.atn.LexerATNSimulator.closure(LexerATNSimulator.java:455)
        at org.antlr.v4.runtime.atn.LexerATNSimulator.closure(LexerATNSimulator.java:455)
        at org.antlr.v4.runtime.atn.LexerATNSimulator.closure(LexerATNSimulator.java:455)
        at org.antlr.v4.runtime.atn.LexerATNSimulator.closure(LexerATNSimulator.java:455)

Не уверен, что я я пропал. Образец грамматики отлично работает, поделитесь здесь

1 Ответ

1 голос
/ 05 августа 2020

Похоже, что виноват недопустимый диапазон 9-_ в вашем классе символов [a-zA-Z0-9-_]. Если вы правильно экранируете -, исключение не генерируется:

IDENT : [a-zA-Z][a-zA-Z0-9\-_]*;
...