Hi Tim,
Here's a link to JavaCC.
http://javacc.dev.java.net/
I just learned how to modify the core language syntax recently. Here's a
quick set of steps. Maybe one of us should write a "how-to" for new
Velocity developers.
(1) Modify "Parser.jjt" to change the syntax of the language
(2) Use jjtree (part of javacc) to compile to Parser.jj. This will also
generate a lot of "Node" java files which you should delete
(3) Use javacc to compile "Parser.jj" to "Parser.java".
(4) Edit the Node java files in the Nodes subdirectory to change evaluated
behavior.
(5) Compile, build the jar as usual
JJTree is a pre-processor that generates java code which stores a tree of
parsed syntax. All the Node files in the Nodes subdirectory were once
generated by JJTree, but have since been modified and moved into the Node
directory (to prevent them from being overwritten in step 2). If you
extend the language and create a new syntactical expression which requires a
new node, you should copy that generated Node file into the Nodes
subdirectory.
So, in reference to my earlier email, you will change the if statment syntax
in "Parser.jjt" to only allow references or method calls. (not a general
expression). This will cause a syntax error to be thrown if the user puts a
full expression in, e.g. ($a > 2) instead of just a reference or method
call. Then, change the code in the Nodes/ASTIfStatement.java to also throw
an exception if a non-boolean reference is passed in.
This gets more complicated if you want the syntax to be allowed/disallowed
via a user switch. The problem is that the syntax definition is compiled
into a wide swath of code in the resulting file Parser.java file. If you
want to have a switch, I'd guess you should then skip steps 1-3, and edit
the evaluation code to throw an eval-time error (as opposed to a parse-time
error that is thrown by default) if the child of the IF node is not a
reference or method node.
WILL
----- Original Message -----
From: "Tim Colson" <[EMAIL PROTECTED]>
To: "'Velocity Developers List'" <[EMAIL PROTECTED]>
Sent: Tuesday, July 01, 2003 1:16 PM
Subject: RE: Can comparisons be limited to true/false?
> Will -
>
> Thanks for the nudge...
> > (1) Write a custom directive #IfBoolean
>
> I wouldn't want a new directive. One of my unstated requirements was
> that the templates would continue to work with a standard velocity
> engine. Good idea, but I apologize for that omission. :-)
>
> Another unstated goal was to explicitly disallow expressions inside the
> #if() so that the templates would heavily limit designers (and me) from
> inadvertantly droping in logic.
>
> #if ($temp < 32) FREEZING #end
> versus
> #if ($temp.isBelowFreezing()) FREEZING #end
>
> The presentation might make FREEZING things bold and blue, but I prefer
> that the presentation layer does NOT define what FREEZING means. In my
> apps, I want that in a biz rule, and besides it likely varies - for
> example if the $temp is in Celsius or Fahrenheit, FREEZING is a
> different thing.
>
> > (2) Alter the Velocity source code. User javacc to compile a revised
> Parser.jjt.
> I'll have to read up a bit more on how javacc works, do you have a good
> reference link?
>
> > Since your syntax currently works in Velocity
> > (you want to limit what's acceptable, not add new syntax),
>
> Sorry, I'm a little confused. Does this mean that Parser.jjt (which I
> assume is a Javacc definition/config file) would -not- need to be
> altered?
>
> BTW - I don't want to break existing parsing functionality... I'd like
> to turn this strictness on/off with a switch on a per-template basis.
> (kinda like in Perl where you can specify a "use Strict;" on a script
> and then the perl interpreter will puke if you do nasty things... but
> you can turn off the flag so that included modules that aren't as picky
> can still run.)
>
> > I don't think you'd have to do
> > anything else. (correction: you'd need to change
> > ASTIfStatement.java to throw an exception for non-boolean references).
> Okay, I'll have a look at that.
>
> > This would be the section to revise in Parser.jjt. You'd
> > need to change
> > "Expression()" to only allow a reference or a method call.
> >
> > void IfStatement() : {}
> > {
> > <IF_DIRECTIVE> [<WHITESPACE>] <LPAREN> Expression() <RPAREN>
> > ( Statement() )+ #Block
> > [ LOOKAHEAD(1) ( ElseIfStatement() )+ ]
> > [ LOOKAHEAD(1) ElseStatement() ]
> > <END>
> > }
>
>
> While I was looking at ASTIfStatement, the first comment says:
> * Please look at the Parser.jjt file which is
> * what controls the generation of this class.
>
> Hmmm... so if I patch that file, will another process of the build
> over-write my changes?
>
> Thanks for the help!
> Timo
>
>
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]