Conditional attribute grammars

36
Conditional Attribute Grammars JOHN TANG BOYLAND University of California, Berkeley Attribute grammars are a useful formalism for the specification of computations on structured terms. The classical definition of attribute grammars, however, has no way of treating condi- tionals non-strictly. Consequently, the natural way of expressing many otherwise well-behaved computations involves a circularity. This paper presents conditional attribute grammars, an ex- tension of attribute grammars that enables more precise analysis of conditionals. In conditional attribute grammars, attribute equations may have guards. Equations are active only when their guards are satisfied. The standard attribute grammar evaluation classes are definable for condi- tional attribute grammars, and the corresponding evaluation techniques can be easily adapted. However, determining membership in standard evaluation classes such as 1-SWEEP, OAG and SNC is NP-hard. Categories and Subject Descriptors: D.3.4 [Programming Languages]: Processors—code gener- ation; compilers; translator writing systems and compiler generators; F.4.2 [Mathematical Logic and Formal Languages]: Grammars and Other Rewriting Systems General Terms: Languages, Theory Additional Key Words and Phrases: Attribute grammars, conditionals, demand evaluation, func- tional dependencies, language processor generators, non-strict evaluation, static analysis 1. INTRODUCTION Attribute grammars [Alblas 1991; Deransart et al. 1988; Knuth 1968] allow a computation on a structured term to be expressed using rules associated with each type of constructor. Traditionally, the terms are parse trees of a context-free grammar; each production in the grammar corresponds to a unique constructor. The advantages of attribute grammars are many, including modu- larity and declarativeness. New productions can be added to the grammar with appropriate rules without disturbing the other rules, thus achieving modular- ity. An attribute grammar is declarative because it does not have an explicit evaluation order; instead it specifies a set of simultaneous equations for any parse tree. An implementation then determines an evaluation order that re- This research was supported in part by the Advanced Research Projects Agency (DoD) under Grant MDA972-92-J-1028, and by the National Science Foundation under Infrastructure Grant CDA-8722788. The content of the information does not necessarily reflect the position or the policy of the Government, and no official endorsement should be inferred. Author’s address: John Tang Boyland, 565 Soda Hall # 1776, Department of Electrical Engineering and Computer Science, Computer Science Division, University of California, Berkeley, CA 94720- 1776; email [email protected]. Permission to make digital/hard copy of all or part of this material without fee is granted provided that the copies are not made or distributed for profit or commercial advantage, the ACM copy- right/server notice, the title of the publication, and its date appear, and notice is given that copying is by permission of the Association for Computing Machinery, Inc. (ACM). To copy otherwise, to republish, to post on servers, or to redistribute to lists requires prior specific permission and/or a fee. c 1996 ACM 0164-0925/96/0100-0073 $03.50 ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996, Pages 73–108.

Transcript of Conditional attribute grammars

Page 1: Conditional attribute grammars

Conditional Attribute Grammars

JOHN TANG BOYLANDUniversity of California, Berkeley

Attribute grammars are a useful formalism for the specification of computations on structuredterms. The classical definition of attribute grammars, however, has no way of treating condi-tionals non-strictly. Consequently, the natural way of expressing many otherwise well-behavedcomputations involves a circularity. This paper presents conditional attribute grammars, an ex-tension of attribute grammars that enables more precise analysis of conditionals. In conditionalattribute grammars, attribute equations may have guards. Equations are active only when theirguards are satisfied. The standard attribute grammar evaluation classes are definable for condi-tional attribute grammars, and the corresponding evaluation techniques can be easily adapted.However, determining membership in standard evaluation classes such as 1-SWEEP, OAG andSNC is NP-hard.

Categories and Subject Descriptors: D.3.4 [Programming Languages]: Processors—code gener-ation; compilers; translator writing systems and compiler generators; F.4.2 [Mathematical Logicand Formal Languages]: Grammars and Other Rewriting Systems

General Terms: Languages, TheoryAdditional Key Words and Phrases: Attribute grammars, conditionals, demand evaluation, func-tional dependencies, language processor generators, non-strict evaluation, static analysis

1. INTRODUCTION

Attribute grammars [Alblas 1991; Deransart et al. 1988; Knuth 1968] allowa computation on a structured term to be expressed using rules associatedwith each type of constructor. Traditionally, the terms are parse trees of acontext-free grammar; each production in the grammar corresponds to a uniqueconstructor. The advantages of attribute grammars are many, including modu-larity and declarativeness. New productions can be added to the grammar withappropriate rules without disturbing the other rules, thus achieving modular-ity. An attribute grammar is declarative because it does not have an explicitevaluation order; instead it specifies a set of simultaneous equations for anyparse tree. An implementation then determines an evaluation order that re-

This research was supported in part by the Advanced Research Projects Agency (DoD) underGrant MDA972-92-J-1028, and by the National Science Foundation under Infrastructure GrantCDA-8722788. The content of the information does not necessarily reflect the position or the policyof the Government, and no official endorsement should be inferred.Author’s address: John Tang Boyland, 565 Soda Hall # 1776, Department of Electrical Engineeringand Computer Science, Computer Science Division, University of California, Berkeley, CA 94720-1776; email [email protected] to make digital/hard copy of all or part of this material without fee is granted providedthat the copies are not made or distributed for profit or commercial advantage, the ACM copy-right/server notice, the title of the publication, and its date appear, and notice is given that copyingis by permission of the Association for Computing Machinery, Inc. (ACM). To copy otherwise, torepublish, to post on servers, or to redistribute to lists requires prior specific permission and/or afee.c© 1996 ACM 0164-0925/96/0100-0073 $03.50

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996, Pages 73–108.

Page 2: Conditional attribute grammars

74 · John Tang Boyland

spects the dependencies implicit in the equations.Traditional attribute grammars have a single equation for each attribute to

be assigned for a production. Existing attribute grammar systems invariablypermit conditionals, but a conditional expression is only syntactic sugar for afunction of three parameters, where the boolean first parameter selects one ofthe two others. The formal definition of circularity of attribute grammars doesnot take into account the non-strictness of the conditional. Neither does staticdependency analysis in current systems. In other words, both assume that theboolean and both the “true” and “false” parts of a conditional expression haveto be evaluated. A non-strict analysis would take into account the fact thatonly one of the “true” and “false” parts will be used.

Strict analysis will reject any attribute grammar that uses a condition tochoose between multiple orders in which to visit children in the case that a de-pendency thread runs along the visit order. Such dependencies arise naturallywhen performing subexpression ordering in an attribute grammar [Boylandand Graham 1994]. Subexpression ordering is a code generation task in acompiler. In order to reduce register pressure, the more complex operand to abinary operator is scheduled to execute first. Assume that the code is generatedby appending each instruction to the list of already generated instructions. Thelist generated prior to the expression is “passed” to the more complex operand,and then the new list of instructions is passed to the less complex operand.However, which operand is more complex is not known a priori, thus yieldinga spurious circularity.

Similar circularities may result when computing “offsets” in a compiler fora series of declarations, where each declaration passes on the current offsetto the next declaration. Now suppose a declaration has two sub declarations,one with stronger alignment restrictions that the other. If the current offset isproperly aligned, the former should be given this offset and then the resultingoffset passed to the latter. Otherwise the latter declaration should be given thecurrent offset, and the resulting offset passed to the former.

Figure 1 shows an artificial attribute grammar, the notation for which isdefined in Section 2.1. This example abstracts the relevant properties from anattribute grammar computing offsets. It defines attribute dependencies thatthread through the tree from parent to children and back to parent. For oneparticular production, A → A A, the dependencies are threaded from left-to-right when the starting value is even and otherwise right-to-left.

p0 : S → A

A.i = 0

S.val = A.s

p1 : A → A A

A0.s = if odd(A0.i) then A1.s else A2.s

A1.i = if odd(A0.i) then A2.s else A0.i+1

A2.i = if odd(A0.i) then A0.i+1 else A1.s

p2 : A →A.s := A.i + 1

Fig. 1. A circular attribute grammar

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 3: Conditional attribute grammars

Conditional Attribute Grammars · 75

Attribute grammars such as that of Figure 1 are circular according to theclassical definition given in Section 2.1. Yet if evaluated using demand evalua-tion and treating the conditional non-strictly, this definition need never lead toa circular evaluation for any tree. The same conditional occurs in each of thedefinitions of the attribute equations for p1 but the definition of circularity forattribute grammars has no way of using this information!

One solution to the problem is detection of conditionals that are the same.Then the problem is to define what “the same” means. Using functional equal-ity of the expressions makes circularity testing formally undecidable. Usingany weaker, decidable definition (such as textual equality of the expressions)makes many source-level optimizations unsound. For instance, replacing anexpression with one that computes the same value could make an attributegrammar circular.

If instead of changing the analysis, the structure of attributions is changedso that a conditional need appear in only one place, then there is no need for adefinition of “the same.” In conditional attribute grammars a conditional blockof the following form may appear in any attribute equation list1

if condition thenequation1equation2...

elseequation′1equation′2...

endif

For example, Figure 1 is rewritten as a conditional attribute grammar in Fig-ure 2. Note that the sets of attribution rules are still unordered—conditionalattribution does not describe a side-effecting computation. Note that, as withthe productions, conditions are labelled in order to guarantee uniqueness.According to the definition of circularity for conditional attribute grammars,Figure 1 is still circular, but Figure 2 is not circular. Thus conditional attribu-tion increases expressive power.

The rest of the paper is structured as follows. Section 2 reviews classicalattribute grammars, defines conditional attribute grammars and describes aconstruction relating conditional attribute grammars to classical ones. Sec-tion 3 describes general methods for evaluating both classical and conditionalattribute grammars for particular trees. Efficient implementation (especiallyefficient use of space) requires static analysis to determine an evaluation class.Section 4 extends standard attribute grammar evaluation classes to includeconditional attribute grammars, with corresponding implementation methods.

1Some systems, notably Linguist [Farrow 1982], permit a conditional to be shared among attributeequations in a way similar to conditional attribute grammars. However, this feature is syntacticsugar and does not (currently) affect the analysis.

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 4: Conditional attribute grammars

76 · John Tang Boyland

p0 : S → A

A.i := 0

S.val := A.s

p1 : A → A A

if c : odd(A0.i) then

A0.s = A1.s

A1.i = A2.s

A2.i = A0.i+1

else

A0.s = A2.s

A1.i = A0.i+1

A2.i = A1.s

endif

p2 : A →A.s = A.i + 1

Fig. 2. A conditional attribute grammar

The appendix gives a proof that determining whether a conditional attributegrammar can be evaluated in one pass is NP-hard.

2. DEFINITIONS

This section first defines classical attribute grammars. It then defines condi-tional attribute grammars as an extension. Both formalisms use the underlyingconcept of an algebraic context-free grammar. The final subsection describes atransformation, “node-splitting,” from conditional attribute grammars to clas-sical attribute grammars that preserves dependency information.

This paper uses fairly standard notation (adapted from Alblas [1991] andDeransart et al. [1988]). Note that all the sets described here are finite unlessotherwise specified.

2.1 Classical Attribute Grammars

Following Giegerich [1988], an algebraic context-free grammar is a tuple withfour elements (N,T,Z,P): N is the set of nonterminals, T is the set of ter-minals (N ∩ T = ∅), Z ∈ N is the start symbol, and P is the set of namedproductions. Define Σ ≡ N ∪ T as the set of symbols in the grammar. Eachproduction named p ∈ P has the form p : Xp

0 → Xp1 Xp

2 . . . Xpnp , where

Xp0 ∈ N,Xp

i ∈ Σ, 1 ≤ i ≤ np,np ≥ 0. Define Xp ≡ {Xpi | 0 ≤ i ≤ np}, the set of

symbol occurrences for production p. The only difference between an algebraiccontext-free grammar and a normal context-free grammar is that productionsin the former are named, and so two otherwise identical productions can bedistinguished by their names.

A classical attribute grammar is a tuple (G,S, I,R) where G is an algebraiccontext free grammar, and for each X ∈ Σ,S(X) and I(X) are respectively thesets of synthesized attributes and inherited attributes defined for that symbol(with S(X) ∩ I(X) = ∅). For convenience, we assume that each terminal hasno inherited attributes and a single synthesized attribute, value, (for X ∈T, I(X) = ∅,S(X) = {value}). Define A(X) ≡ S(X) ∪ I(X) as the total set ofattributes for a symbol X. In a slight abuse of notation, we write S(Xp

i ), I(Xpi )

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 5: Conditional attribute grammars

Conditional Attribute Grammars · 77

and A(Xpi ) to refer to the appropriate set of attributes for the nonterminal

associated with the symbol occurrence Xpi . An attribute occurrence is of the

form Xi.a where a ∈ A(Xi). For each production p ∈ P of the form

p : Xp0 → Xp

1 Xp2 . . . Xp

np

Rp is a set of attribution rules relating attribute occurrences. Each rule r hasthe form:

Xpi0.a0 = f (Xp

i1.a1, . . . ,X

pik.ak), where k ≥ 0

where for each 0 ≤ j ≤ k, Xpij∈ Xp and aj ∈ A(Xp

ij), and f is any (appropriately

typed) strict function. Define DO(r) ≡ {Xpi0.a0}, the defined occurrence of rule

r (also known as the output occurrence) and UO(r) ≡ {X pij.aj | 0 < j ≤ k} the

used occurrences of rule r (also known as input occurrences).The attribution rules must be well-formed. The defined occurrence must be

a synthesized attribute of the left-hand side of a production or an inheritedattribute of the right-hand side:

DO(r) ⊆ DOp

where DOp is the set of all attribute occurrences for the production p that maybe defined:

DOp ≡ {Xp0 .a | a ∈ S(Xp

0 )} ∪ {Xpi .a | a ∈ I(Xp

i ), 0 < i ≤ np}There must be precisely one definition for every defined occurrence:⋃

r∈Rp

DO(r) = DOp

DO(r) ∩DO(r′) = ∅, r, r′ ∈ Rp, r 6= r′

For simplicity, the attribute grammar must be in Bochmann normal form[Bochmann 1976]. Only the inherited attributes of the left-hand side andthe synthesized attributes of the right-hand side may be used to compute anattribute value:

UO(r) ⊆ UOp

where UOp is the set of all the attribute occurrences for a production that maybe used:

UOp ≡ {Xp0 .a | a ∈ I(Xp

0 )} ∪ {Xpi .a | a ∈ S(Xp

i ), 0 < i ≤ np}A defined occurrence Xp

i .a ∈ DOp is said to depend on a used occurrenceXp

j .b ∈ UOp (denoted Xpi .b→ Xp

j .a) if the rule r ∈ Rp that defines Xpi .a ({Xp

i .a} =DO(r)) uses Xp

j .b (Xpj .b ∈ UO(r)). The dependency graph of a production is

denoted Dp; the vertices VDp are the attribute occurrences; the edges EDp aredependencies between attribute occurrences:

Dp ≡ (VDp ,EDp)

VDp ≡ DOp ∪UOp

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 6: Conditional attribute grammars

78 · John Tang Boyland

EDp ≡ {Xpj .b→ Xp

i .a | ∃r ∈ Rp, {Xpi .a} = DO(r),Xp

j .b ∈ UO(r)}

For any particular parse tree of the context-free grammar, the dependencygraphs for each production can be pieced together to construct a compounddependency graph for the whole tree. An attribute grammar is circular if thereexists a parse tree of the context-free grammar whose compound dependencygraph has a cycle. For example, Figure 3 shows a compound dependency graphusing the attribute grammar in Figure 1. A cycle is outlined in this figure.Notice that in the tree, the nodes are labeled with both the production andthe nonterminal. Jazayeri, Ogden and Rounds established that determiningwhether an attribute grammar is circular is intrinsically exponential [Jazayeriet al. 1975].

p0:S

p1:A

p2:A p2:A

i

val

sisi

s

Fig. 3. A compound dependency graph for a parse tree (in gray) for the attribute grammar inFigure 1. A cycle is outlined with bold edges.

2.2 Conditional Attribute Grammars

A conditional attribute grammar is a tuple (G,S, I,C,R) where G, S and I areof the same form as in a classical attribute grammar. For each production p,Cp is a set of named conditions used in the attribution rules Rp. Each rule ris either a primary rule, of the classical form, or a conditional rule having theform:

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 7: Conditional attribute grammars

Conditional Attribute Grammars · 79

if cr thenRTr

elseRFr

endif

where RTr ,RFr ⊂ Rp are sets of rules, and cr ∈ Cp is a labelled expression of the

form lr : f (Xpi1 .a1, . . . ,X

pik .ak) for some predicate function f . Conditional rules

may be nested. We refer to the guarding boolean expression cr as the conditionand the members of RTr and RFr as dependent attribution rules. The rules thatare not nested in any conditional rule are called the top-level rules. The set oftop-level rules is denoted R∞. The set of primary rules is denoted R0, and theset of conditional rules R − R0 is denoted RC . All conditions are regarded asdistinct:

|C| = |RC |It is convenient to treat the conditions both as defined occurrences and used

occurrences.2 The definitions of DOp and UOp must be augmented to includethe conditions:

DOp ≡ Cp ∪ {Xp0 .a | a ∈ S(Xp

0 )} ∪ {Xpi .a | a ∈ I(Xp

i ), 0 < i ≤ np}

UOp ≡ Cp ∪ {Xp0 .a | a ∈ I(Xp

0 )} ∪ {Xpi .a | a ∈ S(Xp

i ), 0 < i ≤ np}The definitions of DO(r) and UO(r) for primary rules are extended to applyto conditional rules. For a conditional rule r, DO(r) is defined to include thecondition and all attributes defined in the branches, whereas UO(r) containsonly the condition and the attribute occurrences used in the condition, that is:

DO(r) ≡ {cr} ∪⋃

r′∈RTr ∪RFr

DO(r′), r ∈ RC

UO(r) ≡ {cr} ∪ {Xpij.aj | 1 ≤ j ≤ k}, r ∈ RC

where cr is of the form

lr : f (Xpi1.a1, . . . ,Xp

ik.ak)

As before, all defined occurrences must be in DOp. Normal form requires thatall uses must be in UOp:

DO(r) ⊆ DOp, r ∈ Rp

UO(r) ⊆ UOp, r ∈ Rp

A conditional rule is well-formed only if RTr and RFr define the same set ofattribute occurrences, and each only once: ⋃

r′∈RTr

DO(r′)

− C =

⋃r′∈RFr

DO(r′)

− C, r ∈ RC

2If an attribute grammar formalism contains local attributes, they behave similarly.

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 8: Conditional attribute grammars

80 · John Tang Boyland∧r′ 6=r′′∈R

DO(r′) ∩DO(r′′) = ∅, R ∈ {RTr ,RFr }, r ∈ RC

As with classical attribute grammars, each occurrence in DOp must be definedby exactly one top-level rule:⋃

r∈Rp∩R∞DO(r) = DOp,

∧r6=r′∈Rp∩R∞

DO(r) ∩DO(r′) = ∅

Every attribution rule r ∈ Rp is guarded by zero or more conditions. Wedefine a constraint for each rule, denoted T(r), that expresses when this rule isvalid:

T(r) ∈ Tp

where Tp is the set of all possible constraints, where each constraint is a set ofconstrained conditions, each of which is a pair (c, b), c ∈ C, b ∈ {T ,F}:

Tp ≡ P(Cp × {T ,F})(note that P is the powerset operator.) The constraints, T(r), are definedinductively. Top-level rules are unconstrained:

T(r) ≡ ∅, r ∈ R∞

The dependent rules have the constraint of the surrounding conditional ruleconjoined with the additional constraint for the guarding condition. The con-straint for the true branch constrains the condition to be T ; the constraint forthe false branch constrains it to be F :

T(r′) ≡ T(r) ∪ {(cr, T )}, r′ ∈ RTr , r ∈ RC

T(r′) ≡ T(r) ∪ {(cr,F)}, r′ ∈ RFr , r ∈ RC

A constraint t is inconsistent if it contains both (c, T ) and (c,F) for somecondition c. Otherwise it is consistent. A constraint t is properly structured ifit is consistent and, for a constrained condition c (that is, (c, b) ∈ t, for some b),the constraint for its rule is included in t (T(rc) ⊂ t, where rc is the conditionalrule that tests c). Intuitively, proper structuring ensures that a constraint doesnot constrain an irrelevant condition. Two properly structured constraints tand t′ are compatible (written t ∼ t′) if their union (t∪ t′) is consistent.3 In thiscase, t ∪ t′ is properly structured as well. A properly structured constraint t ismaximal if no further extension t ′ ⊃ t is properly structured. It immediatelyfollows that for every properly structured constraint t, there exists a maximalconstraint t′ that includes it (t′ ⊇ t). Note that a constraint is maximal preciselyif it has the property that it is compatible with another constraint if and onlyif it includes it:

maximal(t)⇔ ∀t′(t ∼ t′ ⇔ t ⊇ t′

)If all the conditional rules are at the top level (RC ⊆ R∞), there are 2|C|

maximal constraints. If they each nest inside the previous one (rci+1 ∈ RTrci∪RFrci

),

3Compatibility is not transitive and thus not an equivalence relation.

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 9: Conditional attribute grammars

Conditional Attribute Grammars · 81

there are only 1 + |C| maximal constraints. The worst-case exponential is thecause of much of the complexity of analyzing conditional attribute grammars.

The conditional dependency graph (D ′p) for a production p is defined overattribute occurrences with constraints labeling the edges:

D′p ≡ (VD′p ,ED′p )

VD′p ≡ UOp ∪DOp

ED′p ⊆ UOp × Tp ×DOp

The graph has edges for each rule; all occurrences defined by that rule dependon all the occurrences used by that rule. The definition omits self-cycles froma condition to itself.

ED′ ≡ {ut→ d | u ∈ UO(r), t = T(r),d ∈ DO(r),u 6= d, r ∈ R}

Note that the definitions of DO(r) and UO(r) for a conditional rule r imply thatany attribute occurrence defined somewhere within a conditional rule dependson all the guarding conditions and all the attribute occurrences used in thoseconditions. As defined, conditional dependency graphs may have redundantedges,4 but it is simpler to define properties on the full graph.

A set of edges {uiti→ di} is valid, if the union of the constraints,

⋃i ti is

properly structured. Thus, considered as a set of edges, a path V0t1→ V1

t2→. . .

tn→ Vn, (n > 0), is valid if t1 ∪ t2 ∪ . . . ∪ tn is properly structured. Such apath is a valid cycle if V0 = Vn. By virtue of normal form, the conditionaldependency graph for a single production p, D ′p, has no cycles (let alone validcycles) and only a few non-trivial paths. All paths of more than one edge gothrough conditions and all are valid. Valid cycles are of interest when we buildup more complicated conditional dependency graphs.

A conditional dependency graph H = (VH,EH) is unconditionalized (written|H|) by removing the conditions and the constraints from the edges:

|H| ≡ (VH − C, {u→ d | u t′→ d ∈ EH})H may be specialized with respect to a particular constraint t (written H↓t) byselecting all edges whose constraint is compatible with t, as well as removingirrelevant condition nodes:

H↓t ≡ (VH − {c ∈ C | T(rc) 6∼ t}, {u t′→ d ∈ EH | t′ ∼ t})For a given parse tree, a compound conditional dependency graph is created

by fitting together the graphs for each production in the parse tree. Eachinstance of a production’s dependency graph gets an independent set of con-ditions. A conditional attribute grammar is circular if any such resulting

4For example, if both the edges ut→ d and u

t′→ d occur and the first is weaker than the second(t ⊂ t′), then the second can be omitted. Similarly if two edges’ constraints differ only for a single

condition (ut]{(c,T )}→ d and u

t]{(c,F)}→ d), they can be replaced by the single edge where no

mention is made of that condition (ut→ d).

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 10: Conditional attribute grammars

82 · John Tang Boyland

odd(.)

p0:S

p1:A

p2:A p2:A

i s

val

sisi

T

F

T

F TF

{(odd(.),T)}

{(odd(.),F)}F

T

{}

Legend:

=

=

=

Fig. 4. A conditional dependency graph for the conditional attribute grammar in Figure 2. Thelabels on the arcs are abbreviated; the legend gives the full form. The only cycle is highlighted; itis invalid.

dependency graph for any tree has a valid cycle. The conditional attributegrammar is unconditionally non-circular if no such graph ever has any cycle(even an invalid one). The dependency graph in Figure 4 has no valid cycle.But it does contain a cycle, and so the conditional attribute grammar is notunconditionally non-circular.

According to the definition of conditional circularity, each conditional is as-sumed unpredictable and independent of any other conditional. A conditionalmay always evaluate to a certain value, but the definition does not take thisinformation into account. For example, the following conditional attributegrammar is circular even though no dynamic circular dependency is possible:ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 11: Conditional attribute grammars

Conditional Attribute Grammars · 83

p0 : S → Aif c : false thenA.i := A.s;

elseA.i := 0;

endif;S.val := A.s

p1 : A →A.s = A.i + 1

Even though c is always false, there is a cycle involving A.i and A.s in the com-pound conditional dependency graph. Although crude, this example shows thatconditional dependency analysis is not sufficient to accurately predict dynamiccircularities. Indeed, full accuracy requires solving the halting problem.

2.3 Node Splitting

As it happens, the types of dependencies that arise in conditional attributegrammars can arise also in classical attribute grammars. This subsection de-fines a transformation, node splitting, that takes a conditional attribute gram-mar and produces a classical attribute grammar with the same dependencystructure. In particular, a conditional attribute grammar is circular preciselywhen the node-split version is circular according to the classical definition ofcircularity. This section includes a proof of this equivalence as Theorem 1. Thegreat body of research on dependencies in classical attribute grammars is thusimmediately applicable to conditional attribute grammars.

The transformation produces attribute equations using an undefined value⊥(read “bottom”). For the purposes of dependency analysis, ⊥ is an ordinary con-stant. As described in Section 2.3.1, it can be used to guide a non-deterministicevaluation of the node-split attribute grammar.

For a conditional attribute grammar α = (G,S, I,C,R) over the algebraiccontext-free grammar G = (N,T,Z,P), the node-split attribute grammar is aclassical attribute grammar ns(α) = (G′,S, I,R′) over a new grammar G′ =(N,T,Z,P′). There is one production pt ∈ P′ in the new grammar for eachproduction p ∈ P in the original grammar and each maximal constraint t ∈ Tp:

P′ ≡ {pt : Xp0 → Xp

1 Xp2 . . . Xp

np| p : Xp

0 → Xp1 Xp

2 . . . Xpnp∈ P, t ∈ Tp}

Note that all the derived productions pt for p have the same shape as p. Notealso that if there are no conditions, |C| = 0, then the only maximal constraintis the empty set and thus P′ is isomorphic to P.

The rules r′ ∈ R′ are derived from the top-level rules in the conditionalattribute grammar:

Rpt ≡⋃

r∈R∞∩Rp

S(r, t)

where S(r, t) is the set of derived attribution rules for rule r and maximalconstraint t. Primary rules are carried over unchanged:

S(r, t) ≡ {r}, r ∈ R0

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 12: Conditional attribute grammars

84 · John Tang Boyland

The derived rules for a conditional rule are those from the appropriate arm ofthe conditional; ⊥ is used if the run-time value of condition does not match theconstraint:

S(rc, {(c, T )} ∪ t) ≡ {d = if c then e else ⊥ | d = e ∈ S(rT, t), rT ∈ RTrc}

S(rc, {(c,F)} ∪ t) ≡ {d = if c then ⊥ else e | d = e ∈ S(rF, t), rF ∈ RFrc}

The node-split version of the example in Figure 2 is given in Figure 5.Observe that although the node-split version duplicates conditions as in Fig-ure 1, the node-split version itself is not circular! By splitting the dependenciesin either arm of the conditional into separate productions, the circularities inFigure 1 are avoided.5 Figure 6 illustrates one possible dependency graph.

The proof of the theorem showing dependency equivalence between a con-ditional attribute grammar and its node-split version is aided by Lemma 1.This lemma states that the conditional dependency graph for a production pspecialized with respect to a maximal constraint t differs from the dependencygraph for the derived production pt only by having conditions.

LEMMA 1. For any production p in a conditional attribute grammar α andany maximal constraint t ∈ Tp, |D′p↓t| = Dpt.

PROOF. Both graphs are defined on the same set of vertices, V = (UOp ∪DOp)−Cp. An edge u→ d exists in Dpt if and only if u is used in the right-handside of the equation defining d. An attribute occurrence u is used in a right-hand side, either if it used in the base expression or in one of the wrappers inwhich the base expression is embedded (or in both places). The former caseoccurs precisely when there exists a primary rule r defining d (d ∈ DO(r)) andusing u (u ∈ UO(r)), whose condition is compatible with t (T(r) ∼ t). The lattercase occurs precisely when a conditional rule r has these same properties. Thusan edge u→ d exists in Dpt if and only if u→ d exists in |D′p↓t|. Therefore thegraphs are identical.

THEOREM 1. A conditional attribute grammar α is circular if and only if theclassical attribute grammar ns(α) is circular.

PROOF. Let α be a circular conditional attribute grammar. Let H be theconditional dependency graph for a parse tree that exhibits a valid cycle. Weconstruct an isomorphic parse tree for ns(α). For each instance of a productionp in the tree, the valid cycle traverses a possibly empty valid set of edgesfrom D′p. Let t be any maximal extension of the union of the constraintsalong the edges in the set. For the constructed parse tree, choose productionpt. By Lemma 1, the dependency graph for this production includes all the(unconditionalized) paths of the set. Consequently the dependency graph for

5Alblas gives a definition of classical attribute grammars that permits semantic conditions [Alblas1991]. These conditions allow certain syntactically correct trees to be “rejected” by the attributegrammar. This form could be used to simplify the node splitting construction, but it would notproperly record which attributes depended on the condition and which did not. A constructionusing this feature would not satisfy Theorem 1.

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 13: Conditional attribute grammars

Conditional Attribute Grammars · 85

p0{} : S → A

A.i = 0

S.val = A.s

p1t0 : A → A A (t0 = {(odd(A0.i), T )})A0.s = if odd(A0.i) then A1.s else ⊥A1.i = if odd(A0.i) then A2.s else ⊥A2.i = if odd(A0.i) then A0.i+1 else ⊥

p1t1 : A → A A (t1 = {(odd(A0.i),F)})A0.s = if odd(A0.i) then ⊥ else A2.s

A1.i = if odd(A0.i) then ⊥ else A0.i+1

A2.i = if odd(A0.i) then ⊥ else A1.s

p2{} : A →A.s = A.i + 1

Fig. 5. The node-split version of Figure 2

p0:S

p2:A p2:A

i s

val

sisi

Ap1F :

Fig. 6. A dependency graph for the (node-split) attribute grammar in Figure 5

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 14: Conditional attribute grammars

86 · John Tang Boyland

the constructed parse tree exhibits a corresponding cycle. Therefore ns(α) iscircular.

Let α be a conditional attribute grammar whose node-split version ns(α) iscircular. Let H be the dependency graph for a parse tree that exhibits a cyclein ns(α). We construct an isomorphic parse tree in the original grammar, bysimply using the base production p for every derived production p t. By Lemma 1again, we can piece together a cycle in the conditional dependency graph forthis tree. Each set of paths in the original dependency graph comes from thedependency graph Dpt , and thus there is a corresponding set of paths in D′p↓t.These paths exist as a valid set in D′p since t is maximal (and thus properlystructured). Since each production instance’s conditions are independent, theresulting cycle is valid. Therefore α is circular.

2.3.1 Non-Determinism in the Node-Split Grammar. Assuming we have atree in the original grammar, a derived tree can be produced non-deterministi-cally and attributed using the rules of the node-split attribute grammar. Foreach instance of a production in the original tree, the dynamic values of theconditions are “guessed” and an instance of the appropriate derived productionis used in the derived tree. If an attribute’s value consequently turns out to be⊥, the dynamic value of some condition does not match the value “guessed” forit. Obviously, no practical implementation can be built from this evaluationmodel. The following section shows how conditional attribute grammars canbe evaluated directly.

3. EVALUATION

This section describes dynamic evaluation methods for arbitrary non-circularclassical and conditional attribute grammars. These methods do not requirestatic analysis, but use resources less efficiently than the implementationsin Section 4 which require static analysis. The standard dynamic attributeevaluation techniques (for example, Jourdan’s evaluation method [Jourdan1984a]) carry over to conditional attribute grammars with little change. Thissection also introduces the concept of a conditional total order that is used hereand later in the paper.

3.1 Forward Evaluation

For a classical attribute grammar, evaluation for a particular tree can be donein three steps. First the whole tree’s dependency graph is constructed. Then,assuming it contains no cycle, a topological sort of the attributes is performed.The resulting total order is used to direct attribute evaluation.

A more efficient method combines the last two steps. Any attribute with nopredecessors is evaluated and then it and any edges from it are removed fromthe graph. The process is repeated until all attributes are evaluated. Eitherversion of this method is called forward evaluation. Both start with attributeswhose values are known and move forward to evaluate attributes that dependonly on these known values.

Forward evaluation can also be carried out on conditional attribute gram-mars. Unfortunately, the dependency graph is not always cycle-free, even forACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 15: Conditional attribute grammars

Conditional Attribute Grammars · 87

odd(.)

p0:S

p1:A

p2:A p2:A

i s

val

sisi

T

F TF

{(odd(.),T)}

{(odd(.),F)}F

T

{}

Legend:

=

=

=

START

TF

TF

FT

T F

Fig. 7. A conditional total order for the conditional dependency graph in Figure 4As before the labels on the arcs are abbreviated. The total order specialized for the maximalconstraint {(odd(A0 .i), T )} is highlighted.

noncircular conditional attribute grammars. Even cycles that are not valid pre-vent a topological sort. Instead, one must construct a conditional total order.A conditional total order is a special case of a conditional dependency graph.It takes the form of a chain that bifurcates at every condition node. One of thetwo subchains is labeled with a constraint that includes (c, T ) and is the sub-chain used if the condition evaluates to “true.” The other subchain is labeledwith a constraint that includes (c,F) and is used if the condition evaluates to“false.” For example, a conditional total order for the conditional dependencygraph in Figure 4 is given in Figure 7. Note that the last two nodes in each ofthe subchains are identical. Using such information may allow a conditional

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 16: Conditional attribute grammars

88 · John Tang Boyland

total order to be represented compactly (although in the worst case, it requireson the order of 2|C|n edges, where |C| is the total number of conditions in thegraph and n is the number of nodes in the graph). A conditional order can bespecialized for a particular constraint. A maximal constraint leads to a totalorder on the attributes, as seen in the figure.

A conditional total order O = (V,EO) is compatible with a non-circular con-ditional dependency graph H = (V,EH) if their combination (V,EO ∪ EH) hasno valid cycles.

To perform a forward evaluation, one constructs the conditional dependencygraph, constructs a compatible conditional total order and then evaluates at-tributes in order. Whenever a conditional is evaluated, the subchain corre-sponding to the result of the predicate is chosen. Analogously to classicalattribute grammars, it is not necessary to construct the conditional total or-der. The more efficient method works as follows. Some node in the conditionaldependency graph that has no predecessors is chosen and evaluated. If itis a condition, the graph is specialized with the appropriate constraint (thuspotentially removing edges and irrelevant condition nodes). In any case, thenode and all edges leaving it are removed. This process is repeated until allattributes are evaluated. This method for forward attribute evaluation takestime linear in the number of edges in the dependency graph.

In both these methods, a crucial detail has been glossed over. For the firstmethod, we need an algorithm for constructing the conditional total order.For the second, we need a guarantee that the process does not stall, thatis, that there will always be a node without predecessors in a non-circularconditional dependency graph. We satisfy both problems by showing thatthe greedy algorithm given can be used to construct a conditional total order,with the modification both possibilities are pursued at every condition node.When used for evaluation, the algorithm runs in time linear in the size ofconditional dependency graph. When used to construct a conditional totalorder, the running time is exponential in the number of condition nodes.

LEMMA 2. Any non-circular conditional dependency graph H has a compati-ble conditional total order. Moreover the greedy algorithm in Figure 8 constructsone.

(If there is a valid cycle, the algorithm will stall, because none of the nodesalong such a cycle will ever be removed for a t consistent with the union of theconstraints on its edges.)

PROOF. First note that for all recursive calls to genCTO, every constraint inHold is compatible with t. It is also true that every edge in the original Hbetween nodes still in Hold is also still in Hold as long as its constraint iscompatible with t. Observe, moreover, that genCTO is called once for everyproperly structured constraint t, and Hold is empty only when t is maximal.

This proof has two parts. First it shows that the algorithm only stalls for acircular H. Next it demonstrates that the generated conditional total order iscompatible with the input.

Let H be a non-circular conditional dependency graph. For each recursivecall to genCTO, let V∞ be the top-level nodes in the graph Hold, that is, the setACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 17: Conditional attribute grammars

Conditional Attribute Grammars · 89

genCTO(Hold,t) -- return (starting node, CTO)

if Hold = (∅, ∅) then

return (END, ({END}, ∅))elsif ∃n ∈ VHold

, 6 ∃n′,n′ → n ∈ EHoldthen

let Hnew ≡ Hold \ nif n ∈ C then

let tT ≡ t ∪ {(n, T )}let (nT,OT ) ≡ genCTO(Hnew↓tT,tT )let tF ≡ t ∪ {(n,F)}let (nF,OF ) ≡ genCTO(Hnew↓tF,tF)

return (n,OT ∪ OF ∪ ({n, nT,nF}, {n tT→ nT,ntF→ nF}))

else

let (n′,O′) ≡ genCTO(Hnew,t)

return (n,O′ ∪ ({n, n′}, {n t→ n′}))endif

else

stall

endif

genCTO(H,∅)

Fig. 8. An algorithm for creating a compatible conditional total order for a conditional dependencygraph H.

of nodes that have unconditional definitions with respect to t, together withconditions that are nested only in conditions constrained by t:

V∞ = {n ∈ VHold | ut′→ n ∈ EHold ⇒ t′ ⊆ t}

If t = ∅, the V∞ is precisely the set of instances of attributes defined by top-levelprimary rules and instances of conditions of top-level conditional rules. Forother t, one can think of each constrained condition as selecting the appropriateset of rules for the instance of that condition, exposing nested attribution rules.Then V∞ is, as before, the set of nodes whose definition rules are unconstrained.The rest of this part of the proof shows that if the algorithm stalls, there willbe a cycle among the nodes in V∞.

Note that every node not in V∞ must depend on instances of conditionsnot constrained by t. Some of these instances may themselves be from con-ditions nested inside conditional rules, the instance of whose condition is un-constrained by t. However, at least one of these conditions will belong to V∞.Consequently, the set V∞ cannot be empty unless Hold is empty. Note alsothat the constraint on a dependency edge from a top-level condition to one ofthe nodes that depends on it is always included in t. Thus if v ∈ V∞ has apredecessor w, either the predecessor itself is in V∞ or else w depends on acondition c in V∞. Therefore every top-level node with a predecessor can bereached along a path of one or two edges from another top-level node. Theconstraints on these edges are all included in t.

If the algorithm stalls, every node must have a predecessor. Thus a validcycle through the top-level nodes exists with every constraint included in t.Therefore, the algorithm stalls if and only if there is a valid cycle in H.

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 18: Conditional attribute grammars

90 · John Tang Boyland

Next, it is shown that the algorithm yields a conditional total order thatis compatible with the input conditional dependency graph. If the generatedconditional total order O were not compatible with H, there must be a validcycle in the combination of O with H. Let tc be a maximal extension of theunion of the constraints along this cycle. The set of edges on the cycle thatcame from H is a valid set. Likewise, the set of edges that came from O is validand lies within O↓tc, a total order of the nodes in H. Consider the recursivechain of calls from the initial call to the call to genCTO with Hold = (∅, ∅), t = tc.One of these recursive calls will be the first one in which a node from the cycleis removed from the graph. Let (Hold, t) be the recursive parameters for thiscall and let n0 be this first node. Note that t is included in tc, t ⊆ tc. But inorder that n0 be removed, it must have no predecessors in Hold. Consider thepredecessor of n0 in the cycle. Since n0 is the first node to be removed, thepredecessor must exist in VHold . Similarly the edge between the two must existin EHold as its constraint is included in tc and thus is compatible with t ⊆ tc.But that would prevent n0 from being removed. Thus it is impossible for thealgorithm to produce an incompatible conditional total order.

By Theorem 1, the node-split attribute grammar represents the same depen-dencies as its conditional attribute grammar. Corollary 1 follows immediately:

COROLLARY 1. A conditional dependency graph H has a compatible condi-tional total order if and only if all of the specialized graphs |H↓t| (t maximal)have compatible total orders.

This correspondence leads one to consider whether a conditional total ordercould be constructed from a set of total orders. Unfortunately, this is not thecase. Total orders are extensions of partial orders. Two different total ordersfor the same partial order are always incompatible. For example, in the graphwith no edges, any order is a compatible total order, but no two total ordersare compatible. Even though a conditional total order uses condition nodes tocombine different total orders, the total orders may differ too early for any con-dition. As a result, it is necessary to construct a conditional total order directlyfrom the conditional dependency graph. Similarly, as Section 4 will describe,an implementation of a conditional attribute grammar must work directly withthe conditional dependency graphs rather than by massaging an unconditionalimplementation of the node-split version of the attribute grammar.

3.2 Demand Evaluation

One can also evaluate a classical attribute grammar for a particular tree byimmediately attempting to evaluate any desired attributes. This method iscalled demand evaluation because the algorithm “demands” the values of theseattributes. Typically the synthesized attributes of the root are demanded.Often an attribute cannot be evaluated since it depends on other attributeswhose values are not (yet) known. A demand evaluation method works byrecursively demanding the values of these attributes. Eventually, assumingthere is no circular dependency, the values will be returned and the attributewill be computed. By remembering what attributes are currently pendingevaluation, it is possible to detect circularities rather than go into an infiniteACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 19: Conditional attribute grammars

Conditional Attribute Grammars · 91

loop. If the attribute values are cached, demand evaluation is “optimal” in thatno attribute is evaluated unnecessarily or more than once.

Note that since an implementation language invariably includes a non-strictconditional, treating conditional expressions in an attribute grammar non-strictly is straightforward. As a result, demand evaluation can be used onmany attribute grammars that are formally circular but never have dynamiccircular dependencies. Demand evaluation, therefore, can be used on con-ditional attribute grammars. When the value of an attribute of a node isdemanded, one first demands the result of any guarding conditionals. Onceall guarding conditionals are known, the correct primary rule is known, thevalues of any attribute occurrences used on the right hand side are demanded.

3.3 Limitations of Demand Evaluation

Demand evaluation avoids constructing a dependency graph and thus usesspace better than forward evaluation. But it still requires a cache for allattributes in the tree in order to be optimal. It also needs one or two bitsper attribute to indicate whether the attribute is evaluated or not (the secondbit would be used for pending evaluation to detect cycles). Static analysismay show that a more restrictive implementation method is possible, suchmethods may require less storage and may also be more easily incrementalized.For example, if an attribute grammar can be evaluated in one pass, all theattributes can be stored in a stack that only gets as deep as the tree is tall.

The following section discusses some standard attribute grammar evaluationclasses and how membership in a class can be used to generate a more efficientimplementation.

4. STATIC ANALYSIS AND EVALUATION CLASSES

A number of attribute evaluation classes have been defined for attribute gram-mars (see, for example, the review by Deransart et al [1988]). If an attributegrammar is found to be in a certain membership class, certain implementa-tion techniques are possible. These techniques may use space better than adynamic algorithm, or they may have good incremental behavior. In order togain these benefits for conditional attribute grammars, the evaluation classesare extended to conditional attribute grammars:

Definition 1. A conditional attribute grammar α belongs to an attributegrammar evaluation class Y if ns(α) belongs to Y.

This definition immediately yields a membership algorithm; one constructs thenode-split version and then uses the classical membership test.

Unfortunately, the nondeterminism of the node-split version of a conditionalattribute grammar makes it unsuitable for implementation. Moreover, it is notpossible in general to convert a (nondeterministic) implementation of a node-split attribute grammar into a deterministic implementation of a conditionalattribute grammar, because all these methods involve generating total orderscompatible with certain dependencies. Therefore, in order to get a determinis-tic implementation of a conditional attribute grammar, it is necessary to createa new algorithm for generating the implementation. For each evaluation class,

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 20: Conditional attribute grammars

92 · John Tang Boyland

a membership test is given for both classical and conditional attribute gram-mars. The membership test for conditional attribute grammars can be usedto generate an implementation corresponding to the implementation of theclassical attribute grammars in the same class.

This section introduces successively more powerful evaluation classes:

1-SWEEP ⊂ l-ORD ⊂ DNC ⊂ SNC ⊂WF

where WF is the class of non-circular (“well-formed”) attribute grammars.Each evaluation classe Y includes those attribute grammars that are stillnon-circular even under certain simplifying assumptions of the dependenciesbetween the attributes. These assumptions can be expressed as additional setsof edges added to the dependency graphs for each production:

DpY ≡ (VDp ,EDp ∪ EY)

Similarly, Y includes those conditional attribute grammars which are still non-circular even with extra edges in the conditional dependency graphs for eachproduction:

D′pY ≡ (VD′p ,ED′p ∪ E′Y)

The following subsections explains each of the evaluation classes in turn.

4.1 Single Pass Attribute Grammars (1-SWEEP)

This section discusses the 1-SWEEP class of attribute grammars. The assump-tion used in this class is that all synthesized attributes depend on all the in-herited attributes. In other words, no synthesized attributes can be evaluateduntil all the inherited attributes are ready. If an attribute grammar permitsthis approximation while remaining non-circular, it is possible to evaluate allthe attributes in one pass over the tree. Attributes may be stored in a stackbounded by a constant times the height of the tree. Moreover, as soon as theattributes of a node have been evaluated, the node can be discarded. Thereforemembership in 1-SWEEP means that an implementation can be very spaceefficient.

Another, equivalent, view of the 1-SWEEP class is that it includes thoseattribute grammars where for every nonterminal, the synthesized attributescan be evaluated as a strict function of all the inherited attributes. Moreover,within each production, there exists a permutation of the children that permitsthe evaluation of the attributes of each child in turn. The class of 1-SWEEP(and multi-SWEEP) attribute grammars were first discussed by Engelfriet andFile [1981a; 1981b]. Determining whether a classical attribute grammar is1-SWEEP is polynomial in the size of the attribute grammar.

More formally, membership in 1-SWEEP can be defined using dependencygraphs. An attribute grammar is 1-SWEEP if and only if for every production,an augmented dependency graph has no valid cycle. This augmented graphincludes edges that express the assumption that every synthesized attribute ofa child depends on all the inherited attributes:

DpSWEEP ≡ (VDp ,EDp ∪ {Xp

i .a→ Xpi .b | 0 < i ≤ np,a ∈ I(Xp

i ), b ∈ S(Xpi )})

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 21: Conditional attribute grammars

Conditional Attribute Grammars · 93

Since all the attributes are treated identically, one can substitute all the inher-ited attribute occurrences Xp

i .a(a ∈ I(Xpi )) with a single node Xp

i .I and similarlywith the synthesized attributes. By virtue of the normal form, this graph hasthe same properties as one where a single node is used for all attributes of achild, synthesized or inherited:

BpSWEEP ≡ (Xp, {Xp

i → Xpj | ∃X

pi .a→ Xp

j .b ∈ EDp , 0 < i, j ≤ np})

Note that if this graph is non-circular, it has a total order. Such a totalorder of the children may be used to generate an implementation. An eval-uation function is constructed for each symbol X ∈ Σ. This function takes anode and its inherited attributes and returns the values of the synthesized at-tributes. For nonterminals, the function body determines the production andthen evaluates the children in some order:

function eval:X(node,V01,V02, . . . ,V0m0) beginif node is production p : Xp

0 → Xp1 ,X

p2 , . . .X

pnp then

(Vi11,Vi12, . . . ,Vi1m1) := eval:Xpi1(X

pi1, expi11, expi12, . . . , expi1p1);

(Vi21,Vi22, . . . ,Vi2m2) := eval:Xpi2(X

pi2, expi21, expi22, . . . , expi2p2);

. . .(Vin1,Vin2, . . . ,Vinmn) := eval:Xp

in(Xpin, expin1, expin2, . . . , expinpn);

return (exp01, exp02, . . . , exp0p0)elsif . . .. . .

endif;end;

where each expij is the right hand side of an equation

Xpi .aj = exp

where attribute uses Xpi′ .aj′ are replaced by uses of the local variables Vi′j′ . The

static analysis that shows the attribute grammar to be 1-SWEEP ensures thatno local variable Vij is used before it is defined. The functions for the terminalsymbols simply return the value attribute.

Note that we cannot immediately apply this technique to a node-split versionof a conditional attribute grammar because this technique requires identifyingthe production before performing any attribute evaluation. Instead we willgenerate an evaluation that is a sequence of statements that either are assign-ment statements of the form of the classical SWEEP implementation or are ifstatements: such as

if condition then...

else...

endif;

where each branch has a list of statements.ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 22: Conditional attribute grammars

94 · John Tang Boyland

Similar to the case of classical attribution grammars, we can define theaugmented conditional dependency graph and the child conditional dependencygraph.

D′pSWEEP ≡ (VD′p ,ED′p ∪ {Xpi .a

{}→ Xpi .b | 0 < i ≤ np,a ∈ I(Xp

i ), b ∈ S(Xpi )})

B′pSWEEP ≡ (Xp ∪ Cp, {u t→ d | ∃u′ t→ d′ ∈ ED′p ,u = base(u′),d = base(d′)})

base(c) ≡ c, c ∈ Cbase(Xp

i .a) ≡ Xpi , 0 < i ≤ np,a ∈ A(Xp

i )

Being in the form of a conditional dependency graph, the child conditionaldependency graph B′pSWEEP is a conditional total order if and only if it is notcircular. From this fact and the correspondence between the node-split versionwith the conditional attribute grammar follows the following theorem:

THEOREM 2. A conditional attribute grammar α is 1-SWEEP (that is, thenode-split version ns(α) is 1-SWEEP) if and only if no child conditional depen-dency graph B′pSWEEP has a valid cycle.

PROOF.

A 1-SWEEP implementation of a conditional attribute grammar may beconstructed from the conditional total order of the children for each production.Bifurcations in the conditional total order are represented by “if” statements.The implementation of Figure 2 is given in Figure 9.

function eval:S(node) begin

if node is production p0 : S → A then

As := eval:A(A,0);

return As;

endif;

end;

function eval:A(node,Ai) begin

if node is production p1 : A → A1 A2 then

if odd(Ai) then

A2s := eval:A(A2,Ai+1);

A1s := eval:A(A1,A2s);

return A1s;

else

A1s := eval:A(A1,Ai+1);

A2s := eval:A(A2,A1s);

return A2s;

endif;

elsif node is production p2 : A → then

return Ai+1;

endif;

end;

Fig. 9. 1-SWEEP implementation of Figure 2

The construction runs in worst-case time exponential in the number of con-ditionals. This worst case happens whenever all the conditionals are at theACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 23: Conditional attribute grammars

Conditional Attribute Grammars · 95

top-level. By doing simplifications on the conditional total order while it is be-ing generated, it is possible to do better than this by merging identical ends inthe arms of an “if” statement before they are constructed. Unfortunately, anyalgorithm for checking 1-SWEEP for conditional attribute grammars is likelyto be exponential in the number of conditionals anyway since the problem isNP-hard (see Appendix).

4.2 Ordered Attribute Grammars

The class of l-ordered attribute grammars, l-ORD, is a larger class than 1-SWEEP or in fact any n-SWEEP. In an attribute grammar of this class, theattributes for each symbol X ∈ Σ can be evaluated in a fixed (total) order.This information can be used to improve the space and time efficiency of animplemented attribute grammar [Kastens 1991].

A family of total orders O, where O(X) is a total order on the attributesfor X ∈ Σ, is consistent with the dependency graph for a production p if thedependency graph augmented with these orders is non-circular:

Dpl-ORD ≡ (VDp ,EDp ∪ {Xi.a→ Xi.b | a→ b ∈ O(X)})

An attribute grammar is l-ordered if there exists such a consistent family oftotal orders. Figure 10 shows an l-ordered attribute grammar. The total orderfor A is {i1→ s1→ i2→ s2}. This attribute grammar cannot be evaluated inone pass; in fact, it cannot be evaluated in any fixed number of passes.

It is easy to check whether a given family of total orders is consistent withall of the productions, but determining whether a consistent family exists isNP-complete [Engelfriet and File 1982]. Kastens defined a subclass of l-ORDknown as OAG (ordered attribute grammars) where the total orders can becomputed using a greedy algorithm that runs in polynomial time [Kastens1980]. A description of this algorithm is deferred to the following subsection,because it uses the DNC test.

The family of total orders can be used to create an implementation whereeach node in the parse tree “remembers” the point in the total order divid-ing unevaluated from evaluated attributes. Consistency ensures it can also“remember” how far evaluation has progressed for each of its children’s at-tributes. Evaluation proceeds whenever a node is requested to evaluate thenext attribute in its order. If it needs an attribute from a child, it can requestevaluation in the child to progress to the point where the attribute is ready.Once it has all the attributes that the requested attribute depends upon, it cancompute the value, advance its own state and return. Note that the parentdefines a child’s inherited attributes, and so a node will only be called upon toevaluate synthesized attributes. When a synthesized attribute is requested,all inherited attributes preceding it have already been evaluated.

This intuition is formalized in visit sequence implementations. A visit se-quence implementation for a production p is constructed from a visit sequence,that is, a total order of the attributes in Dp

l-ORD. This order includes attributes ofthe production and its children. Each visit in the sequence starts with a seriesof inherited attributes of the production and ends with a series of synthesizedattributes of the production. Each visit implementation involves a series of

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 24: Conditional attribute grammars

96 · John Tang Boyland

p0 : S → A

A.i1 = S.in

A.i2 = A.s1

S.out = A.s2

p1 : A → A A

A1.i1 = A0.i1

A1.i2 = A1.s1

A0.s1 = A1.s2

A2.i1 = A0.i2

A2.i2 = A2.s1

A0.s2 = A2.s2

p2 : A →A.s1 = A.i1 + 1

A.s2 = A.i2 + 2

S.in visit_S1(p0 : S → A)

A.i1 A.i1 := S.in;

A.s1 visit_A1(A);

A.i2 A.i2 := A.s1;

A.s2 visit_A2(A);

S.out S.out := A.s2;

A0.i1 visit_A1(p1 : A0 → A1 A2)

A1.i1 A1.i1 := A0.i1;

A1.s1 visit_A1(A1);

A1.i2 A1.i2 := A1.s1;

A1.s2 visit_A2(A1);

A0.s1 A0.s1 := A1.s2;

A0.i2 visit_A2(p1 : A0 → A1 A2)

A2.i1 A2.i1 := A0.i2;

A2.s1 visit_A1(A2);

A2.i2 A2.i2 := A2.s1;

A2.s2 visit_A2(A2);

A0.s2 A0.s2 := A2.s2;

A.i1 visit_A1(p2 : A →)

A.s1 A.s1 := A.i1 + 1;

A.i2 visit_A2(p2 : A →)

A.s2 A.s2 := A.i2 + 2;

Ai2:i1: :s1 :s2

Ai2:i1: :s1 :s2Ai2:i1: :s1 :s2

Fig. 10. An l-ordered attribute grammar, a visit sequence for each production and the implemen-tation of each visit sequence. Below is the dependency graph for production p1 (augmented by atotal order on the attributes of A)

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 25: Conditional attribute grammars

Conditional Attribute Grammars · 97

attribute computations of inherited attributes of the children, visits to a childfor its synthesized attribute and ends with the computation of the synthesizedattributes. The next visit to that node takes up where the last visit left off.Each nonterminal’s productions have a visit sequence with the same numberof visits computing the same synthesized attributes. One may think of thevisit sequence implementation as being a coroutine that temporarily returnscontrol to its parent between visits. Alternatively, one may think of the visitsequence implementation as being a sequence of visit function bodies for thatproduction. Each production of a nonterminal will have its own visit functionbodies. Each nonterminal has a visit function for each visit. The visit functionimplicitly selects the body appropriate for the production of the argument node.

Figure 10 shows a visit sequence implementation for the attribute grammar.Each visit sequence and its implementation are shown in the right column.Notice that the nonterminal S has but one visit function, visit_S1, where Ahas two, visit_A1 and visit_A2. The visit functions visit_A1 and visit_A2have two bodies each, one for each production of A. Notice that the first visitfor A (that is, the function visit_A1) needs to make both visits for the firstchild of production p1. This attribute grammar was constructed to require anunbounded number of passes per tree, but it can be easily handled using a finitenumber of visits per node.

By definition, a conditional attribute grammar is l-ORD if its node-splitversion is l-ORD. Similarly to the SWEEP case, however, a deterministic im-plementation requires a conditional dependency graph for each production:

D′pl-ORD ≡ (VD′p ,ED′p ∪ {Xpi .a

{}→ Xpi .b | a→ b ∈ O(X)})

If this graph does not have a valid cycle, a conditional total order is generated.The conditional total order is used to generate a conditional visit sequenceimplementation.

The resulting conditional visit sequences look rather strange (see Figure 11).It is necessary to return from visit_A1 while inside the “if” statement andthen for visit_A2 to continue executing in the appropriate arm. This feat canbe accomplished by saving the conditional state in the node and testing it uponthe next visit. Alternatively, coroutines can be used. At the end of each visit,execution is suspended; execution resumes with the next visit. Conditional visitsequence evaluators appear similar to the Kennedy and Warren evaluators forthe SNC class [Kennedy and Warren 1976]. In both cases there is a potentialworst-case exponential size. Further research is needed to determine whetherthese superficial similarities reflect a deeper correspondence.

4.3 Double Non-Circular Attribute Grammars

Doubly Non-Circular (DNC) attribute grammars are those for which a consis-tent set of partial orders R(X) exists for the attributes of each nonterminal.Certain incremental implementation methods are applicable to DNC attributegrammars [Jourdan and Parigot 1991; Parigot 1988], but for this paper, theDNC class is primarily of interest as a basis for Kasten’s OAG algorithm.

The partial orders R(X) approximate the dependencies between attributesof a symbol X ∈ Σ. They are constructed by finding the least fixpoint to some

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 26: Conditional attribute grammars

98 · John Tang Boyland

p0 : S → A

A.i1 = S.in

A.i2 = A.s1

S.out = A.s2

p1 : A → A A

if c : odd(A0.i1) then

A1.i1 = A0.i1

A0.s1 = A1.s2

A2.i1 = A0.i2

A0.s2 = A2.s2

else

A2.i1 = A0.i1

A0.s1 = A2.s2

A1.i1 = A0.i2

A0.s2 = A1.s2

endif

A1.i2 = A1.s1

A2.i2 = A2.s1

p2 : A →A.s1 = A.i1 + 1

A.s2 = A.i2 + 2

visit_S1(p0 : S → A)

A.i1 := S.in;

visit_A1(A);

A.i2 := A.s1;

visit_A2(A);

S.out := A.s2;

visit_A1(p1 : A0 → A1 A2)

if odd(A0.i1) then

A1.i1 := A0.i1;

visit_A1(A1);

A1.i2 := A1.s1;

visit_A2(A1);

A0.s1 := A1.s2;

visit_A2(p1 : A0 → A1 A2)

A2.i1 := A0.i2;

visit_A1(A2);

A2.i2 := A2.s1;

visit_A2(A2);

A0.s2 := A2.s2;

else

A2.i1 := A0.i1;

visit_A1(A2);

A2.i2 := A2.s1;

visit_A2(A2);

A0.s1 := A2.s2;

visit_A2(p1 : A0 → A1 A2)

A1.i1 := A0.i2;

visit_A1(A1);

A1.i2 := A1.s1;

visit_A2(A1);

A0.s2 := A1.s2;

endif

visit_A1(p2 : A →)

A.s1 := A.i1 + 1;

visit_A2(p2 : A →)

A.s2 := A.i2 + 2;

Fig. 11. An l-ordered conditional attribute grammar and a conditional visit sequence implementa-tion

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 27: Conditional attribute grammars

Conditional Attribute Grammars · 99

set inequalities (given below). For a production p, the dependency graph isaugmented with the dependencies that are implied in the R set (as constructedso far) for each of the symbol occurrences in the rule. Then any new implieddependencies (paths in the augmented graph) are added to appropriate R set.

DpDNC ≡ (VDp ,EDp ∪

⋃j≥0

R(Xpj ))

R(Xpj ) ⊇ {a→ b | Xp

j .a = V0 → V1 → . . .→ Vk = Xpj .b in Dp

DNC}An attribute grammar is doubly non-circular (DNC) if none of the resultingaugmented dependency graphs for the production is circular. Because anytotal order O(X) must include the partial order R(X), DNC includes l-ORD.

If the attribute grammar is DNC, Kasten’s OAG algorithm extends each ofpartial orders R(X) into a total order O(X). First all a ∈ I(X) that have nopredecessors are placed in the order. These attributes are removed from thepartial order and all a ∈ S(X) without predecessors are selected to be addedto the order. This process is continued until all attributes have been addedto the order. After all the orders have been constructed, one must determinewhether they are consistent with the productions. If this test fails, the attributegrammar is not OAG even though it might be l-ordered.

The DNC test and Kasten’s algorithm can be applied with no change tothe node-split version of a conditional attribute grammar. Alternatively, onemay define the sets directly on the conditional dependency graph. One addsnew dependencies to R(X) only for valid paths in the augmented conditionaldependency graph:

D′pDNC ≡ (VD′p ,ED′p ∪ {Xpi .a

{}→ Xpi .b | a→ b ∈ R(X)})

R(Xpj ) ⊇ {a→ b | Xp

j .a = V0t1→ V1

t2→ . . .tn→ Vn = Xp

j .b valid in D′pDNC}Next each partial order R(X) is extended into an (unconditional) total orderO(X) using Kasten’s algorithm. Finally, the generated orders are tested againstthe l-ORD augmented conditional dependency graph D ′pl-ORD for each produc-tion.

The name “doubly non-circular” implies some singly non-circular evaluationclass. The following subsection describes just such a class.

4.4 Strongly Non-Circular Attribute Grammars

The strictly non-circular (SNC) class of attributes grammars [Courcelle andFranchi-Zannettacci 1982] (first described under the name “absolutely non-circular” attribute grammars [Kennedy and Warren 1976]) is the broadestevaluation class discussed in this paper. The intuition behind SNC is that eachsynthesized attribute of the left-hand side of a production depends directlyor indirectly on a set of the inherited attributes. The approximation used inSNC is to assume that if such a dependency exists for some production of anonterminal, it must exist for all productions for the nonterminal.6

6If an attribute grammar α has only one synthesized attribute per nonterminal, and all inheritedattributes are used in every production, all our classes are the same: 1-SWEEP(α)⇔ l-ORD(α)⇔

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 28: Conditional attribute grammars

100 · John Tang Boyland

In essence, the dependencies for all the productions for a nonterminal arecombined. These dependencies are represented in an input-to-output graphIO(X) for each symbol X ∈ Σ. (A functional version of IO is known as theargument selector). The IO graphs are computed using a fixpoint computationsimilar to that of the R(X) used in the DNC test in the previous subsection. TheR(X) graphs however also include dependencies from synthesized to inheritedattributes, whereas IO(X) only has dependencies from inherited to synthesizedattributes.7 As with other classes, the approximation is used to augment thedependency graph for each production:

DpSNC ≡ (VDp ,EDp ∪

⋃j>0

IO(Xpj ))

IO(Xp0 ) ⊇ {Xp

0 .a→ Xp0 .b | X

p0 .a = V0 → V1 → . . .→ Vn = Xp

0 .b in DpSNC}

Note that the IO graph is only updated for the nonterminal of the left-handside of the production, and thus by normal form, a can only be an inheritedattribute and b only a synthesized attribute. An attribute grammar is SNC ifnone of the augmented dependency graphs is circular. Kennedy and Warrengive a polynomial algorithm for determining whether an attribute grammar isSNC [Kennedy and Warren 1976].

p0 : S → L

L.inh1 = 0

L.inh2 = L.syn1

S.result = L.syn2

p0′ : S → L

L.inh2 = 0

L.inh1 = L.syn2

S.result = L.syn1

p1 : L →L.syn1 = L.inh1 + 1

L.syn2 = L.inh2 + 2

Fig. 12. A simple strongly non-circular attribute grammar

Figure 12 gives an example of a simple strongly non-circular attribute gram-mar that is not DNC (and thus not l-ORD or 1-SWEEP). The IO graph forthe nonterminal L contains the edges {inh1 → syn1, inh2 → syn2}, but thecorresponding R(L) for the DNC test contains a cycle.

One method of implementing SNC attribute grammars generates a set ofmutually recursive functions [Jourdan 1984b]. This method is similar to theSWEEP implementation in Section 4.1, but instead of having one function for anonterminal that takes all the inherited attributes and returns the synthesized

DNC(α)⇔ SNC(α)⇔WF(α).7The partial order R(X) can be seen as the combination of IO(X) and the corresponding OI(X)sets, hence the term “doubly non-circular.”

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 29: Conditional attribute grammars

Conditional Attribute Grammars · 101

attributes, we have one function for each synthesized attribute of a nonterminalthat takes only those inherited attributes necessary to compute the result.These functions are called synth functions [Farrow 1984; Jourdan 1984b]. Eachfunction body determines to which production the subtree belongs, evaluates asubset of the attributes for the production, and returns the desired synthesizedattribute. An implementation of the attribute grammar in Figure 12 is givenin Figure 13. In practice, a cache of attribute values is used as well to avoidexponential evaluation time.

function S:result(node) begin

if node is production p0 : S → L then

return L:syn2(L,L:syn1(0));

elsif node is production p0′ : S → L then

return L:syn1(L,L:syn2(0));

endif;

end;

function L:syn1(node,L:inh1) begin

if node is production p1 : L → then

return L:inh1 + 1;

endif;

end;

function L:syn2(node,L:inh2) begin

if node is production p1 : L → then

return L:inh2 + 2;

endif;

end;

Fig. 13. Synth function implementation of Figure 12

As with 1-SWEEP, a conditional attribute grammar is SNC if and only if thenode-split version is SNC as a traditional attribute grammar. The conditionalattribute grammar in Figure 14 is SNC under this definition. (In fact, thenode-split version of this attribute grammar is almost the same as the attributegrammar in Figure 12.)

As with the earlier evaluation classes, SNC can be defined directly on theconditional dependency graphs:

D′pSNC ≡ (VD′p ,ED′p ∪ {Xpi .a

{}→ Xpi .b | a→ b ∈ IO(Xp

i ), i > 0})

IO(Xp0 ) ⊇ {Xp

0 .a→ Xp0 .b | X

p0 .a = V0

t1→ V1t2→ . . .

tn→ Vn = Xp0 .b valid in D′pSNC}

Then one can create the synth functions by computing a conditional total orderon D′pSNC and so interleave conditional evaluations and attribute evaluations.Figure 14 gives an implementation of the strongly non-circular conditionalattribute grammar using synth functions. It is almost identical to that in Fig-ure 13. The only difference is that instead of using the production to choosebetween two different computations of the result value, the value of the con-dition is the deciding factor. Conditional synth function implementations donot differ much from the unconditional variety. This correspondence may shedlight on the possible connection between conditional OAG and unconditionalSNC implementations.

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 30: Conditional attribute grammars

102 · John Tang Boyland

p0 : S → L

if c : S.cond then

L.inh1 = 0

L.inh2 = L.syn1

S.result = L.syn2

else

L.inh2 = 0

L.inh1 = L.syn2

S.result = L.syn1

endif;

p1 : L →L.syn1 = L.inh1 + 1

L.syn2 = L.inh2 + 2

function S:result(node,S:cond) begin

if node is production p0 : S → L then

if S:cond then

return L:syn2(L,L:syn1(0));

else

return L:syn1(L,L:syn2(0));

endif;

endif;

end;

function L:syn1(node,L:inh1) begin

if node is production p1 : L → then

return L:inh1 + 1;

endif;

end;

function L:syn2(node,L:inh2) begin

if node is production p1 : L → then

return L:inh2 + 2;

endif;

end;

Fig. 14. A strongly non-circular conditional attribute grammar and an implementation

4.5 Discussion

So far all our examples of conditional attribute grammars belong to a particularclass if analyzed “correctly” (that is, conditionally) and otherwise are circular.A question that arises is whether unconditional analysis works correctly onunconditionally non-circular conditional attribute grammars. Equivalently,the question is whether Y ∩ |WF| = |Y|, where |WF| is the set of unconditionalnon-circular (“well-formed”) attribute grammars and |Y| is the unconditionalversion of some evaluation class Y.

It turns out that unconditional analysis can be fooled by all sorts of spuri-ous dependencies, even ones that do not cause circularity. For example theattribute grammar in Figure 15 is in 1-SWEEP, but analyzed unconditionallyis only |SNC|, not |1-SWEEP| nor even |l-ORD|.

4.6 Summary

This section presented the 1-SWEEP, OAG, DNC and SNC evaluation classes.Each was defined for classical and then for conditional attribute grammars.Most of these classes have a characteristic evaluation method: 1-SWEEP at-tribute grammars can be be evaluated in one pass over the tree; l-ORD at-tribute grammars can be implemented using visit sequences; SNC attributegrammars can be evaluated using a recursive function for each synthesized at-tribute. These implementation methods all carry over to conditional attributegrammars, with some changes to handle the conditionals.

These implementation methods can be used because a static analysis hasdetermined what dependencies will not occur at run-time. It is not necessaryto build a dependency graph at run-time, nor is it necessary to remember whichACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 31: Conditional attribute grammars

Conditional Attribute Grammars · 103

p0 : S → A A

if c0 : S.cond then

A1.i1 = 0

A1.i2 = 0

A2.i1 = A1.s1

A2.i2 = A1.s2

S.result = A2.s1 + A2.s2

else

A1.i1 = 0

A1.i2 = A2.s1

A2.i1 = 0

A2.i2 = 0

S.result = A1.s1 + A1.s2 + A2.s2

endif

p1 : S → A A

if c1 : S.cond then

A1.i1 = 0

A1.i2 = 0

A2.i1 = A1.s1

A2.i2 = A1.s2

S.result = A2.s1 + A2.s2

else

A1.i1 = A2.s2

A1.i2 = 0

A2.i1 = 0

A2.i2 = 0

S.result = A1.s1 + A1.s2 + A2.s1

endif

p2 : A →A.s1 = A.i1 + 1

A.s2 = A.i2 + 1

Fig. 15. SWEEP ∩ |SNC| 6⊆ |l-ORD|

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 32: Conditional attribute grammars

104 · John Tang Boyland

attributes have been evaluated and which not. As a result the implementationbased on one of tehse methods often uses space more efficiently.

5. CONCLUSION

This paper has described conditional attribute grammars, an extension to clas-sical attribute grammars that permits a wider number of attribute dependen-cies to be non-circular. As has been shown, standard attribute evaluationclasses such as 1-SWEEP, l-ORD and SNC can be extended to conditional at-tribute grammars. Corresponding implementation techniques are applicable.

The extension has at least two useful aspects. First, it allows attributedependencies to depend on the results of attribute evaluation, such as was seenin Figure 2. Such dependencies can arise, for instance, in simple instructionscheduling, when a more complex subexpression is scheduled to be evaluatedbefore a simpler one. Conditional attribute grammars handle the most directway of expressing this task.

Second, such dependencies may arise in the composition of two tree transfor-mation stages, each expressed as an attribute grammar (such transformationsare also called attribute coupled grammars [Ganzinger and Giegerich 1984;Giegerich 1988]). If the first transformation uses “if” expressions to choosebetween two different output shapes, the descriptional composition of the twostages will result in a conditional attribute grammar. If the result is analyzedas a classical attribute grammar, it may be circular even though neither of theoriginal stages is circular [Boyland and Graham 1994].

Static analysis of conditional attribute grammars apparently requires algo-rithms with worst case running times that are exponential in the number ofconditionals. The worst case only applies in the case when all the conditionalsare independent and when each branch of the conditional induces different(incompatible) dependencies. Dependencies in common between the branchescan be factored out and redundant conditional dependencies can be removed inan analysis prepass. Moreover, the types of conditional dependencies that leadto the worst-case running time even after such optimizations are by their verynature hard to reason about. The possibility of such complex dependencies arethe reason why the static circularity problem for classical attribute grammarsis provably exponential, even though such cases rarely or ever arise in prac-tice. Thus it seems plausible that with a simplifying prepass, the extensionsof standard attribute grammar analysis algorithms to conditional attributegrammars will prove tractable in most cases cases seen in practice.

APPENDIX

This appendix shows that the problem (referred to as CSWEEP) of determiningwhether a conditional attribute grammar is in 1-SWEEP is co-NP-complete, byshowing that the complement of CSWEEP (CSWEEPc) is NP-complete. It isshown that CSWEEPc is in NP and then SATISIFIABILITY (satisfiability of aboolean expression in conjunctive normal form) is reduced to CSWEEP c.

A problem in CSWEEPc is stated as follows: given a conditional attributegrammar α, is there some production in the node-split version of α (that is,ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 33: Conditional attribute grammars

Conditional Attribute Grammars · 105

some production p and a maximal constraint t) such that the child dependencygraph Bpt

SWEEP has a cycle?First a construction from SATISFIABILITY to CSWEEPc is described. Let

U = {u1,u2, . . . ,un} be a set of boolean variables and E =∧

1≤j≤m∨

i≤k≤pjzjk be

a boolean expression in conjunctive normal form over U (z jk ∈ U ∪ U, whereU = {u | u ∈ U}). Without loss of generality n,m,pj > 0. From E a conditionalattribute grammar α is constructed:

α = (G, {result, syn, s, value}, {inh, i},C,R)G = ({S, P, X}, {I}, S,P)

S(S) = {result}S(P) = {s}S(X) = {syn}S(I) = {value}I(P) = {i}I(X) = {inh}

P = {p0 : S→ I P,p1 : P→ X X X . . .X,p2 : X→}

It has three nonterminals S, P, and X each with a single production and oneterminal Iwhose value is an arbitrary integer. The production for P has m(n+2)children each of which is the X nonterminal (named X−1 . . . X−m X11 X12 . . . Xij. . . Xnm X+

1 . . . X+m; the superscripts + and − are merely used for distinguishing

purposes and do not have any meaning in themselves). There is one inheritedattribute each for P and X and one synthesized attribute each for S, P, X and I.The attribute rules R are

p0 : S → I PP.i = I.valueS.result = P.s

p1 : P → X−1 . . . X−m X11 X12 . . . Xij . . . Xnm X+1 . . . X+

mX−1 .inh = X+

m.synX−j .inh = X+

j−1.syn 1 < j ≤ mX+

j .inh = X1j.syn + . . . + Xnj.syn 1 ≤ j ≤ mP.s = P.i + X+

m.synif ci : P.i & 2i then -- bitwise "and" 1 ≤ i ≤ n

Xij.inh = eij 1 ≤ j ≤ melse

Xij.inh = eij 1 ≤ j ≤ mendif

p2 : X →X.syn = X.inh

The expression eij is X−j .syn if ui occurs as a literal in the j’th clause of E,otherwise it is 0. Similarly eij is X−j .syn if ui occurs as a literal in the j’th clause

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 34: Conditional attribute grammars

106 · John Tang Boyland

of E, otherwise it is 0. Figure 16 gives an example of this construction. Theintuition behind the construction is that an assignment of truth values for thevariables in U corresponds precisely to an assignment of truth values to theconditions in the production for P. To underscore the relationship, the edges ofthe conditional dependency graph between the children are labeled with theterms zij. The example boolean expression is not satisfiable and the constructedconditional attribute grammar is in 1-SWEEP.

LEMMA 3. E is satisfiable if and only if α is not in 1-SWEEP.

PROOF. An assignment of truth values to the variables satisfies E if and onlyif every conjunct Ej ∈ E is satisfied by that assignment. Each conjunct Ej issatisfied for the assignment if and only if for the corresponding assignmentof truth values to the conditionals in α, X+

j .inh depends on X−j .syn. Moreover,if and only if for each j, X+

j .inh depends on X−j .syn, then X+m.syn depends on

itself and α is circular. Consequently, as each production always uses its (only)inherited attribute to compute its (only) synthesized attribute, α is circular ifand only if α is not in 1-SWEEP.

THEOREM 3. CSWEEPc is NP-complete.

PROOF. CSWEEPc is clearly in NP since, given p, t and a putative cycle, itis easy to verify that the cycle actually exists. From the lemma immediatelyfollows that SATISFIABILITY reduces to CSWEEPc and thus CSWEEPc isNP-hard. Since CSWEEPc is however in NP, it follows that it is NP-completeand thus its complement CSWEEP is co-NP-complete.

Moreover since CSWEEP reduces to COAG or CSNC, the latter problems areNP-hard.

ACKNOWLEDGMENTS

The first draft of this paper was prepared for a class taught by Professor AlexAiken, whose early comments were much appreciated. Professor Susan Gra-ham, John Hauser, Nicholas Weaver, and William Maddox provided usefulcomments on later drafts. The thorough criticism by Manuel Fahndrich isgratefully acknowledged, as are the suggestions of the anonymous referees.

REFERENCES

ALBLAS, H. 1991. Introduction to attribute grammars. In Attribute Grammars, Applica-tions and Systems. SAGA Proceedings, H. Alblas and B. Melichar, Eds. Lecture Notesin Computer Science, vol. 545. Springer-Verlag, 1–15.

BOCHMANN, G. V. 1976. Semantic evaluation from left to right. Commun. ACM 19, 2(Feb.), 55–62.

BOYLAND, J. AND GRAHAM, S. L. 1994. Composing tree attributions. In Conf. Record ofthe 21st Annual ACM SIGACT/SIGPLAN Symposium on Principles of ProgrammingLanguages. 375–388.

COURCELLE, B. AND FRANCHI-ZANNETTACCI, P. 1982. Attribute grammars and recursiveprogram schemes. Theor. Comp. Sci. 17, 163–191,235–257.

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 35: Conditional attribute grammars

Conditional Attribute Grammars · 107

U = {u1, u2} E = (u1 ∨ u2) ∧ (u1 ∨ u2) ∧ u2

p0 : S → I P

P.i = I.value

S.result = P.s

p1 : P → X−1 X−2 X−3 X11 X12 X13 X21 X22 X23 X+1 X+

2 X+3

X−1 .inh = X+3 .syn

X−2 .inh = X+1 .syn

X−3 .inh = X+2 .syn

X+1 .inh = X11.syn + X21.syn

X+2 .inh = X12.syn + X22.syn

X+3 .inh = X13.syn + X23.syn

P.s = P.i + X+3 .syn

if c1 : P.i & 2 then

X11.inh = X−1 .syn

X12.inh = 0

X13.inh = 0

else

X11.inh = 0

X12.inh = X−2 .syn

X13.inh = 0

endif

if c2 : P.i & 4 then

X21.inh = X−1 .syn

X22.inh = X−2 .syn

X23.inh = 0

else

X21.inh = 0

X22.inh = 0

X23.inh = X−3 .syn

endif

p2 : X →X.syn := X.inh

X3−X

2−X

1− X

3+X

2+X

1+

u1

u 2

2

u

1 u

u 2

X11

X21

X12

X22

X13

X23

Fig. 16. A sample construction from SATISFIABILITY to CSWEEPc and the resulting conditionalchild dependency graph B′p1

SWEEP (omitting the condition nodes)

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996

Page 36: Conditional attribute grammars

108 · John Tang Boyland

DERANSART, P., JOURDAN, M., AND LORHO, B. 1988. Attribute Grammars: Definitions,Systems and Bibliography. Lecture Notes in Computer Science, vol. 323. Springer-Verlag, Berlin, Heidelberg, New York.

ENGELFRIET, J. AND FILE, G. 1981a. The formal power of one-visit attribute grammars.Acta Inf. 16, 3 (Nov.), 275–302.

ENGELFRIET, J. AND FILE, G. 1981b. Passes, sweeps and visits. In Automata, Languagesand Programming. Eighth Colloquium (Acre, Israel, 13-17 July 1981), S. Even andO. Kariv, Eds. Springer-Verlag, Berlin, Heidelberg, New York, 193–207.

ENGELFRIET, J. AND FILE, G. 1982. Simple multi-visit attribute grammars. J. Comput.Syst. Sci. 24, 283–314.

FARROW, R. 1982. Linguist-86: yet another translator writing system based on at-tribute grammars. In Proceedings of the ACM SIGPLAN ’82 Symposium on CompilerConstruction. 160–171.

FARROW, R. 1984. Sub-protocol-evaluators for attribute grammars. In Proceedings ofthe ACM SIGPLAN ’84 Symposium on Compiler Construction (Montreal, Quebec,Canada). 70–80.

GANZINGER, H. AND GIEGERICH, R. 1984. Attribute coupled grammars. In Proceedingsof the ACM SIGPLAN ’84 Symposium on Compiler Construction (Montreal, Quebec,Canada). 157–170.

GIEGERICH, R. 1988. Composition and evaluation of attribute coupled grammars. ActaInf. 25, 355–423.

JAZAYERI, M., OGDEN, W., AND ROUNDS, W. 1975. The intrinsically exponential complex-ity of the circularity problem for attribute grammars. Commun. ACM 18, 12 (Dec.),697–706.

JOURDAN, M. 1984a. An optimal-time recursive evaluator for attribute grammars.In International Symposium on Programming 6th Colloquium (Toulouse, France),M. Paul and B. Robinet, Eds. Springer-Verlag, Berlin, Heidelberg, New York, 167–178.

JOURDAN, M. 1984b. Strongly non-circular attribute grammars and their recursiveevaluation. In Proceedings of the ACM SIGPLAN ’84 Symposium on Compiler Con-struction (Montreal, Quebec, Canada). 81–93.

JOURDAN, M. AND PARIGOT, D. 1991. Internals and externals of the FNC-2 attributegrammar system. In Attribute Grammars, Applications and Systems. SAGA Proceed-ings, H. Alblas and B. Melichar, Eds. Lecture Notes in Computer Science, vol. 545.Springer-Verlag, 485–504.

KASTENS, U. 1980. Ordered attributed grammars. Acta Inf. 13, 3 (Mar.), 229–256.KASTENS, U. 1991. Implementation of visit-oriented attribute evaluators. In Attribute

Grammars, Applications and Systems. SAGA Proceedings, H. Alblas and B. Melichar,Eds. Lecture Notes in Computer Science, vol. 545. Springer-Verlag, 114–139.

KENNEDY, K. AND WARREN, S. K. 1976. Automatic generation of efficient evaluators forattribute grammars. In Conf. Record of the 3rd Annual ACM SIGACT/SIGPLANSymposium on Principles of Programming Languages. 32–49.

KNUTH, D. E. 1968. Semantics of context free languages. Math Syst. Theory 2, 2 (June),127–145. Errata Math Syst. Theory 5, 1 (1971), 95–96.

PARIGOT, D. 1988. Transformation, evaluation incrementale et optimisations des gram-maires attribuees: le systeme FNC-2. Ph.D. thesis, Univ. de Paris-Sud.

Received June 1995, Revised December 1995, Accepted December 1995.

ACM Transactions on Programming Languages and Systems, Vol. 18, No. 1, January 1996