[stringtemplate-interest] Why an == operator is sometimes necessary, and how to implement it (ST3/C#)

Terence Parr parrt at cs.usfca.edu
Tue Mar 23 14:26:58 PDT 2010


Hi Harald, it still seems to me that deciding what replacements to do is part of the model not the view. I encapsulate the translation rules primarily in the model unless they are fixed one-to-one mappings, in which case I can do a static map in the template group file.   personally, I figure out what to generate and then ask ST to dump it out in the right format.

Ter
On Mar 12, 2010, at 11:15 AM, Harald Mueller wrote:

> Hi -
> 
> as we all know, ST does not have any expression operators in its language, and that is almost always a good thing. However, in a well-worn code generator we use to create triggers in an SQL database, we finally got to the point where we needed an equals operator in $if(...)$. Here is why; and how we implemented it.
> 
> The problem is as follows: Input to the generation is (a) a list of SQL tables; (b) the FROM part of an SQL statement, which is a tree of join nodes; each join node points to a table (and of course has information about the joined columns and inner/outer etc., but that's not important); and (c) a replacement string (typically "INSERTED" or "DELETED"; but there are more).
> The job to do is to write a trigger for each table in the join tree, such that the table itself is replaced with the replacement string.
> 
> A small example:
> (a) T1, T2
> (b) ... FROM T1 INNER JOIN T2 INNER JOIN T3
> (c) "INSERTED"
> Result:
> ... FROM INSERTED INNER JOIN T2 INNER JOIN T3
> ... FROM T1 INNER JOIN INSERTED INNER JOIN T3
> 
> The example below is a simplified version of the above, however, its ST template marks nodes in a tree with an arrow (<--) if the node's "table name" is equal to the "replacement table".
> 
> Here is the model, together with the "equals operator":
> 
>    public class Table {
>        public string Name;
>    }
> 
>    public class Join {
>        public readonly string Name;
>        public readonly Table JoinedTable;
>        public readonly List<Join> Children;
>        public Join(string name, Table joinedTable, params Join[] children) {
>            Name = name;
>            JoinedTable = joinedTable;
>            Children = new List<Join>(children);
>        }
>    }
> 
> Here are the templates - first the Main template, then the recursive one for printing the tree.
> 
> Main(Target, Tables) ::= <<
>    $Tables:PrintTreeReplacingTable(Target=Target,Replace=it)$
>>> 
> 
> PrintTreeReplacingTable(Target,Replace) ::= <<
>    $Target.Name$ $if(Target.NameIsReplace.(Replace.Name))$ <--	$endif$
> 	$Target.Children:PrintTreeReplacingTable(Target=it,Replace=Replace)$
> 
>>> 
> 
> The important idea here is the expression
> 
>    Target.NameIsReplace.(Replace.Name)
> 
> where .NameEquals is a property that returns an IDictionary. The (Replacement.Name) then passes in a value which is in effect the parameter of a single-arg function which implements "Target.Name == Replace.Name" - that's the whole trick.
> 
> So we extend Join with the following additional property
> 
>    public IDictionary NameEquals {
>        get {
>            return new Equals(JoinedTable.Name);
>        }
>    }
> 
> and the class Equals, which is implemented as follows:
> 
>    class Equals : DictionaryBase, IDictionary {
>        private readonly string _tn;
> 
>        public Equals(string tn) {
>            _tn = tn;
>        }
> 
>        bool IDictionary.Contains(object key) {
>            return key.ToString() == _tn;
>        }
> 
>        object IDictionary.this[object key] {
>            get {
>                return key.ToString() == _tn;
>            }
>            set { throw new NotImplementedException(); }
>        }
>    }
> 
> That's it. Maybe it helps someone.
> And maybe someone's got an idea how this works without that IDictionary trick - but we didn't see how!
> 
> Regards
> Harald M.
> 
> -- 
> GRATIS für alle GMX-Mitglieder: Die maxdome Movie-FLAT!
> Jetzt freischalten unter http://portal.gmx.net/de/go/maxdome01
> _______________________________________________
> stringtemplate-interest mailing list
> stringtemplate-interest at antlr.org
> http://www.antlr.org/mailman/listinfo/stringtemplate-interest



More information about the stringtemplate-interest mailing list