[antlr-interest] ANTLR 3: Problem with static DFA class generation

Terence Parr parrt at cs.usfca.edu
Fri Sep 23 18:54:27 PDT 2005


Hi.  Without altering the code generator *code*, I was easily able to  
change the output to have nonstatic cyclic DFAs thanks to the power  
of StringTemplate. :)

Originally, the parser template had a "hole" for the cyclic DFAs:

<cyclicDFAs>

Aside from removing the "static" keyword everywhere, I added the  
following line in front that applied a template to the DFAs:

     <! define a singleton instance for each cyclic DFA !>
     <cyclicDFAs:{dfa | protected DFA<dfa.decisionNumber>  
dfa<dfa.decisionNumber> = new DFA<dfa.decisionNumber>();}>

which generates a bunch of singletons:

     protected DFA3 dfa3 = new DFA3();
     protected DFA4 dfa4 = new DFA4();
     ...

in addition to the cyclic DFAs.

The list of DFAs is actually a list of templates so I can ask for  
their attributes no problem.  Nothing is converted to string until  
the last minute.  Notice the really great SmallTalk-inspired syntax  
of that template application:

<attributeList:{ iteratorVar | template}>

That was added in StringTemplate 2.2 :)

Anyway, all my unit tests pass, but I'll try to add some more to see  
if they compile ok and can access instance variables.

Thanks for the inspiration Oliver!

Ter

On Sep 19, 2005, at 4:21 AM, Oliver Zeigermann wrote:

> OK, I created patches for the new Java.stg, DFA.java (optional - makes
> predicat non-static) and finally a small one for Codegenerator.java.
> Using them will generate the code below.
>
> Oliver
>
> 2005/9/19, Oliver Zeigermann <oliver.zeigermann at gmail.com>:
>
>> 2005/9/18, Terence Parr <parrt at cs.usfca.edu>:
>>
>>>
>>> On Sep 12, 2005, at 3:41 AM, Oliver Zeigermann wrote:
>>>
>>>> It simple makes all DFA code non static to allow full access to the
>>>> outer class' (Lexer) fields. The part that creates a single DFA per
>>>> decision and lexer like this:
>>>>
>>>> class XMLLexer extends Lexer {
>>>>
>>>> ...
>>>>
>>>> private dfa10 = new DFA10();
>>>>
>>>> ...
>>>>
>>>> alt10 = dfa10.predict(input);
>>>>
>>>> ...
>>>>
>>>> }
>>>>
>>>
>>> Ok, I think figured out why I didn't want to do this before.  There
>>> is a bunch of state construction "new" operations that go on when  
>>> you
>>> say new DFA10().  I only wanted them to occur once as they are
>>> expensive.  I somehow missed the obvious reuse of the outermost DFA
>>> object; here you are using dfa10 to create DFA10 just once.  In this
>>> way, we only create the DFA states once like with static, but the
>>> inner classes have an implied "this" pointer and can see the  
>>> instance
>>> variables of the outer Lexer object.   I like it!
>>>
>>
>> Yes, that's right! My patch does not include the above single
>> construction, as this would have required a bit more than changing a
>> template, though. But I am pretty sure that you know how to do  
>> this...
>>
>> Oliver
>>
>>
>> <Java.stg.diff>
>> <DFA.java.diff>
>> <CodeGenerator.java.diff>
>

--
CS Professor & Grad Director, University of San Francisco
Creator, ANTLR Parser Generator, http://www.antlr.org
Cofounder, http://www.jguru.com



More information about the antlr-interest mailing list