[antlr-interest] Best Practice type Question.

craig at palantir.co.za craig at palantir.co.za
Mon Sep 14 23:52:44 PDT 2009


Hi,

I have pasted the grammar.
What I really need is for the sql template to be able to process paths one way
to generate the join clauses, because I can get the table names from
relativePath (the first part of the part) and the field name(s) from other
parts of the relativePath. I need the sql template to call / use the other
templates to generate first joins, and then where clauses.

Because I am using -> or(l={$p1.st}, r={$p2.st}) the templates are expanded in a
particular way. I want to use the paths parameter to the sql template in
different ways.


xpath
		: d+=declaration* p+=path
		-> sql(declarations={$d}, paths={$p})
		;

declaration	: ^('declare' nsName=QNAME ns=STRING)
		-> declaration(name={$nsName}, namespace={$ns})
		;

path		: ^('or' p1=path p2=path) -> or(l={$p1.st}, r={$p2.st})
		| ^('and' p1=path p2=path) -> and(l={$p1.st}, r={$p2.st})
		| ^('relative-path' rn=rangeExpr) { $xpath::tables.AddRange($rn.re); } ->
template(rn={$rn.st}) "RN:[ <rn> ]"
		;

rangeExpr
returns [string[\] re]
scope			{ List<string> path; }
@init			{ $rangeExpr::path = new List<string>(); }
			: rp+=relativePath*
			{ $re = $rangeExpr::path.ToArray(); }
			-> template(rp={$rp}) "RP:[ <rp; separator=\", \"> ]"
			;

relativePath
	: ('//'|'/') (ns=QNAME ':')? nm=QNAME
	{ $rangeExpr::path.Add( Convert.ToString(((XNamespace) (ns == null ?
XNamespace.None : $ns.Text)) + $nm.Text )); }
	| dot='.' -> {%{$dot.text}}
	| STRING -> {%{$STRING.text}}
	| '@' qn=QNAME -> {%{$QNAME.text}}
	| cm=comp -> template(c={$cm.st}) "<c>"
	;

comp	: ^('comparison' (op='=' | op='<' | op='>' | op='like') lv=relativePath
rv=relativePath)
	-> comparison(path={$rangeExpr::path}, lv={$lv.st}, rv={$rv.st}, op={$op})
	;

[moving to ST interest]

Hi. Are you saying that you want to process the same data with multiple
templates? or are you saying you want a template to be sensitive to the kind of
data it's applied to?
Ter
On Sep 14, 2009, at 2:12 AM, craig at palantir.co.za wrote:

> Hi,
>
> I have a tree grammar that is walking a parsed tree and outputting SQL
> statements using templates.
>
> At particular points in the tree I need to generate join clauses and
> where clauses. The template looks something like this.
>
> sql(tables, paths) ::= <<
> <tables>
> WHERE
> <paths>
>>>
>
> or(l, r) ::= <<
> <l>
> OR
> <r>
>>>
>
> and(l, r) ::= <<
> <l>
> AND
> <r>
>>>
>
> comparison(path, lv, rv, op) ::= <<
> <path> {<lv>} <op> {<rv>}
>>>
>
> paths generates nested OR/AND sections.
> My problem is that tables and paths are essentially the same thing.
> The
> templates need to generate a set of JOIN clauses for the tables part,
> and the set of OR/AND where conditions for the paths part. Only these
> are exactly the same thing.
>
> There seems to be no general way of saying "generate the template once
> in mode 'a', and then again in mode 'b'". I hope I am not being too
> vague. I have the OR/AND clauses generating perfectly and am in the
> process of hacking the table names into a list to generate that part
> of the template. I feel there must be a better way.
>
> Thanks
> Regards
> Craig.
>


----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.




More information about the antlr-interest mailing list