27 March 2000 Release 2.22 Notes for New Users of PCCTS Version 1.33MR22
25
Decisions about which rule of a grammar to apply are made before entering the code which recognizes the rule. If
the semantic predicate is not at the left edge of the production then the decision has already been made and it is too
late to change rules based on the semantic predicate. In this case the semantic predicate is evaluated only to verify
that it is true and is termed a "validation predicate".
#131. Semantic predicates are not always hoisted into the prediction expression
Even if a semantic predicate is on the left edge there is no guarantee that it will be part of the prediction expression.
Consider the following two examples:
a : <<
semantic-predicate
>>? ID glob
/* a1 */
| ID glob
/* a2 */
;
b : <<
semantic-predicate
>>? ID glob
/* b1 */
| Number glob
/* b2 */
;
With
k
=1 rule "a" requires the semantic predicate to disambiguate alternatives a1 and a2 because the rules are
otherwise identical. Rule "b" has a token type of Number in alternative b2 so it can be distinguished from b1
without evaluation of the semantic predicate during prediction. In both cases the semantic predicate will be
validated by evaluation inside the rule.
#132. Semantic predicates can't be hoisted into a sub-rule: "
{x} y
" is not exactly equivalent to "
x y | y
"
Consider the following grammar extract:
class Expr {
e1 : (e2)+ END ;
xid: <<is_xid(LT(1)->getText())>>? ID ;
yid: <<is_yid(LT(1)->getText())>>? ID ;
/* Works */ e2: xid "." yid | yid ; /* a1 */
/* Doesn't work */ e2: {xid "."} yid ; /* a2 */
}
Alternatives a1 and a2 appear to be equivalent, but a1 works on input "abc" and a2 doesn't because only the
semantic predicate of xid is hoisted into production e1 (but not the semantic predicate of yid).
Explanation by TJP: These alternatives are not really the same. The
language
described however is the same. The
rule:
e2: {xid "."} yid ;
is shorthand for:
e2: (xid "." | /* epsilon */ ) yid ;
Rule e2 has no decision to make here - hence, yid does not get its predicate hoisted. The decision to be made for
the empty alternative does not get the predicate from yid hoisted because one can't hoist a predicate
into
a subrule
from beyond the subrule. The program might alter things in the subrule so that the predicate is no longer valid or
becomes valid. Contributed by Kari Grano (kari.grano@varian.com).
#133. How to change the reporting of failed semantic predicates
To make a global change #define the macro zzfailed_predicate(string) prior to the #include of pccts/h/AParser.h
One can change the handling on a case-by-case basis by using the "failed predicate" action which is enclosed in "["
and "]" and follows immediately after the predicate:
a : <<isTypedef(LT(1)->getText())>>?
[{printf("Not a typedef\n");};] ID ;
For an example of conversion of a failed semantic predicate into a parser exception see Example #13.
#134. A semantic predicate should be free of side-effects because it may be evaluated multiple times
Even in simple grammars semantic predicate are evaluated at least twice: once in the prediction expression for a rule
and once inside the rule as a validation predicate to make sure the semantic predicate is valid.
A semantic predicate may be hoisted into more than one prediction expressions.
A prediction expression may be evaluated more than once as part of syntactic predicates (guess mode).