27 March 2000 Release 2.22 Notes for New Users of PCCTS Version 1.33MR22
22
#109. An empty sub-rule can change a regular action into an init-action
A particularly nasty form of the init-action problem is when an empty sub-rule has an associated action:
rule!: name:ID (/* empty */
<<#0=#[ID,$name];>>
| ab:array_bounds
<<#0=#[T_array_declaration,$name],#ab);>>
);
Since there is no reserved word in
PCCTS
for epsilon, the action for the empty arm of the sub-rule becomes the init-
action. For this reason it's wise to follow one of the following conventions
­ Represent epsilon with an empty subrule "()"
­ Put the null rule as the last rule in a list of alternatives:
rule!: name:ID (
() <<#0=#[ID,$name];>>
| ab:array_bounds
<<#0=#[T_array_declaration,$name],#ab);>>
);
The cost of using "()" to represent epsilon is small.
#110. Commenting out a sub-rule can change a leading-action into an init-action
Suppose one comments out a rule in the grammar in order to test an idea:
rule /* a1 */
: <<init-action;>> /* a2 */
//// rule_a /* a3 */
| rule_b /* a4 */
| rule_c /* a5 */
;
In this case one only wanted to comment out the "rule_a" reference in line a3. The reference is indeed gone, but the
change has introduced an epsilon production - which probably creates a large number of ambiguities. Without the
init-action the ":" would have probably have been commented out also, and
ANTLR
would report a syntax error -
thus preventing one from shooting oneself in the foot. See Item #107.
Commenting out a rule can create orphan rules which can lead to misleading reports of ambiguity in the grammar.
To detect orphan rules use the
ANTLR
­info o switch.
#111. Init-actions are executed just once for sub-rules:
(...)+
,
(...)*
, and
{...}
Consider the following example from section 3.6.1 (page 29) of the 1.00 manual:
a : <<List *p=NULL;>> // initialize list
Type
( <<int i=0;>> // initialize index
v:Var <<append(p,i++,$v);>>
)*
<<OperateOn(p);>>
;
Inheritance
#112. Downward inherited variables are just normal C arguments to the function which recognizes the rule
If one is using downward inheritance syntax to pass results back to the caller (really upward inheritance !) then it is
necessary to pass the
address
of the variable which will receive the result.