[antlr-interest] Interesting problem with ANTLR and CSS 2.1 (tokens added to AST rewrites almost works)

Austin Hastings Austin_Hastings at Yahoo.com
Fri Oct 12 23:58:17 PDT 2007


Simon,

You're not asking for what you want. :)

When you say

parse : stylesheet* -> ^(STYLESHEET stylesheet) ;

you are asking for only one stylesheet. When you are faced with a rule 
element that has a cardinality different from "exactly one" you need to 
use a cardinality operator on the right hand side of the -> as well.

Try this:

parse:  stylesheet* -> ^(STYLESHEET stylesheet*) ;

Or for a weird time, try this:

parse: stylesheet* -> ^(STYLESHEET stylesheet)* ;

(Dump them both so you'll grok the difference.)

This trick works with + as well. Sometimes you can use ? too, but I've 
occasionally had to use * on the RHS when I used ? on the left - this is 
3.0.1 after all. :)

=Austin



Simon Janes wrote:
> Thanks dave!
>
> That almost works-- now I no longer get the "more than one node as
> root" error, but only receive one child in the list.  I got this by
> changing the grammar rules here and introducing some "semantic"
> tokens:
>
> ----
> parse	:	stylesheet* -> ^(STYLESHEET stylesheet);
>
> stylesheet
> 	: comment_stylesheet -> ^(COMMENT comment_stylesheet)
> 	| ruleset -> ^(RULESET ruleset)
> 	| media -> ^(MEDIA media)
> 	| page -> ^(PAGE page)
> 	;
> ----
>
> The CSS for this run:
>
> /* hello comment */
> .hello { color: blue; font-face: Arial; }
> .again { color: blue; }
>
> The getStringTree() dump:
>
> (STYLESHEET (COMMENT /* hello comment */))
>
> Is there something I need to do tell it to append to a node?
>
>
>   
>> On Fri, Oct 12, 2007 at 04:23:04PM -0400, Simon Janes wrote:
>>     
>>> parse    :    stylesheet -> ^(stylesheet); /* I think this sets the "root"
>>> of the AST. */
>>>       
>>> stylesheet
>>>     : (comment_stylesheet|ruleset|media|page)* ;
>>>       
>>> I'll get a runtime error:
>>>
>>> "more than one node as root"
>>>       
>> I've not seen that before, but I assume the problem is that..
>>
>>   -> ^(stylesheet)
>>
>> ..attempts to make the AST referenced by 'stylesheet' be the root node of
>> the result AST, but in your case 'stylesheet' does not represent a
>> single node, but a list of nodes.
>>
>> Probably you should just remove the '^'..
>>
>>   parse    :    stylesheet -> stylesheet;
>>
>> ..but then you might as well just remove the rewrite, because it doesn't
>> add anything..
>>
>>   parse    :    stylesheet;
>>
>>
>> Alternatively, you could add an 'imaginary' node to act as the root, if
>> you really want a single node result rather than a list..
>>
>>   parse    :    stylesheet -> ^(STYLESHEET stylesheet);
>>
>>
>> Note that for the standard ANTLR tree implementation, a 'list' of nodes
>> is really just a special case node:
>>
>>   http://www.antlr.org/api/Java/classorg_1_1antlr_1_1runtime_1_1tree_1_1_common_tree.html#670edeb282b219bc714ed9490aa5a728
>>
>>
>> ta,
>> dave
>>
>>     
>
>
>   



More information about the antlr-interest mailing list