[antlr-interest] ANTLR Semantic Predicate Check Exceeding 65535 Bytes Limit
Zachary Palmer
zep_antlr at bahj.com
Fri Oct 29 19:49:51 PDT 2010
Good to know, thanks. :) I'll have to keep a closer eye on the JIRA
from now on. In the end, I wound up writing a custom ANT task to deal
with the problem. This turned out to be a good thing because I very
quickly hit the 64K limit on the size of a Java class initializer too.
I'm just glad I didn't have to write all this myself; the generated
parser is about 63,000 lines at this point. :-P Go go gadget parser
generator!
Thanks again,
Zach
> wow. yeah, known issue.
>
> http://www.antlr.org/jira/browse/ANTLR-393
>
> Ter
> On Oct 25, 2010, at 5:53 PM, Zachary Palmer wrote:
>
>
>> Hello again. :)
>>
>> I seem to have hit an interesting boundary; ANTLR has generated a method
>> which is more than 64K in size. This would be relatively unremarkable -
>> goodness knows that this has happened to other people - except that the
>> particular reason I have encountered seems to be somewhat strange. The
>> following is a method generated in a DFA that ANTLR produced for me:
>>
>> public int specialStateTransition(int s, IntStream _input)
>> throws NoViableAltException {
>> TokenStream input = (TokenStream)_input;
>> int _s = s;
>> switch ( s ) {
>> case 0 :
>> int LA58_0 = input.LA(1);
>> int index58_0 = input.index();
>> input.rewind();
>> s = -1;
>> if ( (LA58_0==128)&&
>> ((((configuration.getMetaprogramsSupported())&&(configuration.getCodeSplicingSupported()))||((configuration.getMetaAnnotationsSupported())&&(configuration.getCodeSplicingSupported()))||((configuration.getMetaAnnotationsSupported())&&(configuration.getCodeSplicingSupported()))||
>> /****** GREAT BIG SNIP ******/
>> ((configuration.getMetaAnnotationsSupported())&&(configuration.getCodeSplicingSupported()))||((configuration.getMetaprogramsSupported())&&(configuration.getCodeSplicingSupported())))))
>> {s = 1;}
>> else if (
>> (LA58_0==ABSTRACT||LA58_0==CLASS||(LA58_0>=ENUM&&
>> LA58_0<=FINAL)||LA58_0==INTERFACE||LA58_0==NATIVE||(LA58_0>=PRIVATE&&
>> LA58_0<=PUBLIC)||(LA58_0>=STATIC&&
>> LA58_0<=STRICTFP)||LA58_0==SYNCHRONIZED||LA58_0==TRANSIENT||LA58_0==VOLATILE||LA58_0==SEMI||LA58_0==MONKEYS_AT)
>> ) {s = 2;}
>> else if ( (LA58_0==METAPROGRAM_START)&&
>> ((configuration.getMetaprogramsSupported()))) {s = 18;}
>> input.seek(index58_0);
>> if ( s>=0 ) return s;
>> break;
>> case 1 :
>> int LA58_1 = input.LA(1);
>> int index58_1 = input.index();
>> input.rewind();
>> s = -1;
>> if (
>> ((synpred64_BsjAntlr()&&(configuration.getCodeSplicingSupported()))) )
>> {s = 19;}
>> else if (
>> ((((configuration.getMetaAnnotationsSupported())&&(configuration.getCodeSplicingSupported()))||(configuration.getCodeSplicingSupported())||((configuration.getMetaprogramsSupported())&&(configuration.getCodeSplicingSupported()))||((configuration.getMetaAnnotationsSupported())&&(configuration.getCodeSplicingSupported()))||((configuration.getMetaAnnotationsSupported())&&(configuration.getCodeSplicingSupported()))||((configuration.getMetaAnnotationsSupported())&&(configuration.getCodeSplicingSupported()))||((configuration.getMetaAnnotationsSupported())&&(configuration.getCodeSplicingSupported()))))
>> ) {s = 18;}
>> input.seek(index58_1);
>> if ( s>=0 ) return s;
>> break;
>> }
>> if (state.backtracking>0) {state.failed=true; return -1;}
>> NoViableAltException nvae =
>> new NoViableAltException(getDescription(), 58, _s, input);
>> error(nvae);
>> throw nvae;
>> }
>>
>> Looks pretty normal... except for the astonishingly common constructs
>> like
>> "(((configuration.getMetaprogramsSupported())&&(configuration.getCodeSplicingSupported()))".
>> In fact, each of these constructs is a semantic predicate applied to a
>> rule I use fairly often: meta-annotations. These are similar to normal
>> annotations in that they can appear in the modifiers clause of any Java
>> declaration (or, additionally, as a prefix to any Java statement). I
>> guarded them with this semantic predicate to allow me to turn my parser
>> into a normal Java parser by fiddling with the configuration; I observed
>> this technique used in the Java 1.5 parser on the ANTLRv3 site and
>> thought it quite sensible.
>>
>> The catch is that the comment /****** GREAT BIG SNIP ******/ above is
>> hiding more than 200,000 characters of code. This same condition is
>> repeated here an enormous number of times. I've looked throughout my
>> parser and discovered that this same pattern appears in many other
>> places as well. In some cases, a generated ANTLR syntactic predicate is
>> also called in this fashion, such as in:
>>
>> if (
>> (((synpred188_BsjAntlr()&&(configuration.getCodeSplicingSupported()))||(synpred188_BsjAntlr()&&(configuration.getCodeSplicingSupported()))||(synpred188_BsjAntlr()&&(configuration.getCodeSplicingSupported()))))
>> ) {
>> alt150=1;
>> }
>>
>> Does anyone have any idea what I've done to so infuriate the gods? I'll
>> probably be using a regular expression to seek through the code and
>> eliminate the most egregious of cases -- I'm already using an ANT script
>> to add @SuppressWarnings annotations to the classes, so it's not that
>> far out of my build process -- but any hint as to how I did this or what
>> I could to do solve it correctly would be quite appreciated.
>>
>> Thanks!
>>
>> - Zach
>>
>> List: http://www.antlr.org/mailman/listinfo/antlr-interest
>> Unsubscribe: http://www.antlr.org/mailman/options/antlr-interest/your-email-address
>>
>
>
More information about the antlr-interest
mailing list