[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: AST Transformations



Hi Roger,

 Sorry about being silent so long time.

  Productions can be transformed to more than one elements.
I think it will be more easy to explain this with an example, so i've
joind a file called tar.grammar in which some precisions are given.


> Hi Etienne, All,
> 
> The new AST transformations are a great feature, and I'm just wondering
> who wrote it I can direct a few questions their way. SableCC is sorely
> in need of good documentation and I am happy to do this providing I
> don't have to reverse engineer everything that is released! It is also
> very difficult to understand the source code due to the lack of (i.e.
> non-existance of) comments.
> 
> My main question is "Do you have to have a 'New' statement for each
> transform, or are there other shortcuts?". 

  No, there are other shortcuts. We have four differents alternative
transformations types (new, simple, list, null).
I've joined a SableCC3 example grammar based on arithmetic expressions, in
which all transformations types are specified(expression.grammar).

  The new statement must appear at least once in alternative
transformations since the AST is composed by node(s) defined in Abstract
Syntax Tree section. 
The only way to create new node in SableCC3 is to write 'New' followed by
a production name and optionnally '.alternative_name' if there is an
alternative name.


 I hope that this could help you.
 I you have any other question, i will be happy to help you.

 Cheers,

 Kevin

>I ask this because I see the
> mention of lists in the source, and also notice that the grammar allows
> more than one transformation to be defined per alternative:
> 
>     alt_transform =
> 	        arrow [terms]: term*;
> 

> Thanks,
> 
> Roger
> 
> On Wed, May 07, 2003 at 01:41:04PM -0400, Etienne Gagnon wrote:
> > Indrek Mandre wrote:
> > >What is the timeline of SableCC 3 anyway? When does it become available?
> > 
> > The CST->AST stuff is ready.  I should be making it public next week, if
> > everything goes well.
> > 
> > You can think of most of the other wish-list items as SableCC X (where X > 
> > 3)
> > wishes.
> > 
> > :-)
> > 
> > Etienne
> > 
> > 
> > -- 
> > Etienne M. Gagnon, Ph.D.             http://www.info.uqam.ca/~egagnon/
> > SableVM:                                       http://www.sablevm.org/
> > SableCC:                                       http://www.sablecc.org/
> > 
> 
> 
> 
> 
Package tar;

Helpers

tab = 9;
cr = 13;
lf = 10;
eol = [[cr + lf] + [cr + lf]];
white = [[' ' + tab] + eol];

lowercase = ['a' .. 'z'];
uppercase = ['A' .. 'Z'];
letter = uppercase;
digit = ['0'..'9'];
id_part = lowercase (lowercase | digit)*;
blank = (' ' | tab | eol)+;

Tokens

  tar = 'tar';
  id = id_part ('_' id_part)*;
  minus = '-';
  semicolon = ';';
  l_bkt = '[';
  r_bkt = ']';
  letter = letter;
  

  blank = blank;

Ignored Tokens

/* These tokens are simply ignored by the parser. */

    blank;

/*****************/
Productions

/***********************************************************************
  The first production of this section must be transformed to the first 
  production of Abstract Syntax Tree section
  but it is not necessary to explicitely specify it if it has the same
  name.
  So, in this case, we should write :
  grammar -> grammar
  but the software automatically do it when nothing is specified.
  So we have less things to do :-)
***********************************************************************/

/*#####*/  
	grammar = P.tar -> New grammar((P.tar.letter), (P.tar.id));  
/*#####*/


/***********************************************************************
 Here the production #tar# is supposed to be transformed to a list of #letter#
 followed by a list of #id#.
 Since the unique alternative of #options# is composed by 
 token #tar#, production #options# and production #files#,
 we can get a list of letter by productions #options# transformations
 and a list of id by production #files# one's.

 As it can be notice here, there is no new statement in this transformation.
 So the 'New' statement is not needed in all cases.
***********************************************************************/

/*#####*/
	tar -> letter* id* = T.tar options files -> (options.letter) (files.id); 
/*#####*/

/***********************************************************************
 #options# is transformed to a list of letter.
 So the alternative transformation #(letter)# means that we created a new list
 in which we add all elements of #elem+#
 So there is no more #options# node in the AST. They are all transformed to lists
 of #letter#.
***********************************************************************/

/*#####*/
	options -> letter*  = minus letter+ -> (letter);
/*#####*/


/***********************************************************************
 This transformation is similar production #tar# transformation
***********************************************************************/
/*#####*/
	files -> id* = file_name+ semicolon? -> (file_name.id) ;
/*#####*/

/***********************************************************************
 In this case, #file_name# is transformed to #id#. So we only get the already 
 existing #id# from the unique alternative.
***********************************************************************/
  file_name -> id = l_bkt id r_bkt -> id;


/*****************/
Abstract Syntax Tree

  grammar = letter* id*;
Package expressionlist;

Helpers

    digit = ['0' .. '9'];

    tab = 9;
    cr = 13;
    lf = 10;
    eol = cr lf | cr | lf; // This takes care of different platforms
    tous = [0 .. 0xffff];
    blank = (' ' | tab | eol)+;

Tokens
    l_par = '(';
    r_par = ')';
    plus = '+';
    minus = '-';
    mult = '*';
    div = '/';
    dot = '.';
    comma = ',';

    blank = blank;
    number = digit+;
    toto = 'toto';
    titi = 'titi';
    tata = 'tata';

Ignored Tokens

    blank;

Productions

    grammar -> grammar = exp_list -> New grammar((exp_list.exp));

    exp_list -> exp* = exp  exp_list_tail -> (exp exp_list_tail.exp);

    exp_list_tail -> exp = comma exp -> exp;

    exp = {plus}   exp plus factor  -> New exp.plus(exp, factor.exp)   |
          {minus}  exp minus factor -> New exp.minus(exp, factor.exp)  |
          {factor} factor 	    -> factor.exp;


    factor -> exp = {mult}      factor mult term -> New exp.mult(factor.exp, term.exp ) |
                    {div}       factor div term  -> New exp.div(factor.exp, term.exp )  |
                    {term}      term 		 -> term.exp;

    term -> exp = {number}   number dummy -> New exp.number(number) |
           	  {exp}      l_par exp r_par   ->  exp;

    dummy ->    = dummychild tata* -> ;

    dummychild -> toto = toto titi -> Null;

Abstract Syntax Tree

    grammar = exp+;

    exp = {plus}   [l]:exp [r]:exp |
	  {minus}  [l]:exp [r]:exp |
	  {div}    [l]:exp [r]:exp |
	  {mult}   [l]:exp [r]:exp |
	  {number} number ;