On Mon, 02 Apr 2001  22:30:56 +0900, Robert Feldt wrote:
> Yeah, its great. Do you know if it is general (ie. you can apply operators
> (?/+/*) to sequences of symbols and nest them or if they only applies to
> individual symbols? (rockit has the latter but not the former)

The operators are generic and apply to both terminals, nonterminals
and grouped symbols (with paren's).

> > semantic_predicates
> > 	:	{ conditional_code; } => rule
> > 	|	{ conditional_code; } => rule
> > 	|	foo
> > 	;
> Ok, and you have access to parsing/lexing info when writing the
> conditional_code? What kind of info? Can you access the AST being built?

LA(1), LA(2) etc access the lookahead tokens, LT(n) accesses the
lookahead token text. You can access token values using a prefix:

	rule
		:	t:TOKEN { emit(t.getText()); }
		;

rules can have parameters

	rule [Array params]
		:	...

call with

	another_rule
	{ a = Array.new } // ;)
		:	(rule[a])*
		;

and return values

	rule returns [String foo]
		:	...

use with =

	another_rule
	{ String a; }
		:	a = rule
		;

or both

	rule [String a] returns [String b]
		:	...

To access the generated AST you can take two approaches:
- iterate over the nodes with your own code, or
- write a treeparser: this allows you to parse the AST with exactly
  the same EBNF constructs used to parse token streams -- LL(k) tree
  parsers!

[snip]
> Interesting. In rockit I've used a different but similar thing:
> 
> mult_expr:    add_expr STAR  add_expr        [Mult:  left, _, right]
>          |    add_expr SLASH add_expr        [Div:   nom, _, denom]
> add_expr:     atom PLUS  atom                [Plus:  left, _, right]
>          |    atom MINUS atom                [Minus: left, _, right]
> atom:         NUMBER                         [^]
> 
> but as you see it's not as terse even though its more flexible. Maybe
> should learn from ANTLR here...

Grammar annotation with ^'s (make a root node) and !'s (don't
auto-generate a node) is the basic stuff. You can generate custom node
using tree construction statements:

	begin!
	    :   INT PLUS i:INT
		{ #begin = #(PLUS INT i); }
	    ;

or

	stmt
		:	IF a:expr THEN b:expr ELSE c:expr
			{ #stmt = #(IF, a, b, c); }
		;

so you're free to design your AST nodes. AST's can also be
heterogeneous, so you can instantiate a different type of node class
for each grammar element (also using a simple grammar annotation).
This let's you build pretty much every kind of AST.

	Michel