Generate parser prod subclasses with null assigned attributes.
[nit.git] / src / parser / xss / prods.xss
1 /* This file is part of NIT ( http://www.nitlanguage.org ).
2  *
3  * Copyright 2008 Jean Privat <jean@pryen.org>
4  * Based on algorithms developped for ( http://www.sablecc.org/ ).
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 $ template make_abs_prods()
20 $ set baseprod = {//prod/@ename}
21
22 $ foreach {//prod}
23 class @ename special Prod end
24 $ end
25
26 $ foreach {//alt}
27 class @ename
28 special ${../@ename}
29 $ foreach {elem}
30 $   if @is_list
31     readable writable attr _n_@name: List[@etype] = null
32 $   else
33     readable writable attr _n_@name: @etype = null
34 $   end
35 $ end
36 end
37 $ end
38
39 class Start
40 special Prod
41     readable writable attr _n_base: $baseprod 
42     readable writable attr _n_eof: EOF 
43 end
44 $ end template
45
46 $ template make_prods()
47 $ set baseprod = {//prod/@ename}
48 $ foreach {//alt}
49 redef class @ename
50 $ foreach {elem}
51 $   if @is_list
52 $   else
53     redef meth n_@name=(n: @etype)
54     do
55         _n_@name = n
56         if n != null then
57             n.parent = self
58         end
59     end
60 $   end
61 $ end
62
63     private init empty_init do end
64
65 $ if {count(elem)!=0}
66     init init_${translate(@ename,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")} (
67 $ foreach {elem}
68 $   if {@is_list}
69             n_@{name}: Array[Object] [-sep ','-] # Should be Array[@etype]
70 $   else
71             n_@{name}: @etype [-sep ','-]
72 $   end
73 $ end
74     )
75 $ else
76     init init_${translate(@ename,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")}
77 $ end
78     do
79         empty_init
80 $ foreach {elem}
81 $   if @is_list
82         _n_@{name} = new List[@{etype}]
83         for n in n_@{name} do
84                 assert n isa @{etype}
85                 _n_@{name}.add(n)
86                 n.parent = self
87         end
88 $   else
89         _n_@name = n_@{name}
90         if n_@{name} != null then
91                 n_@{name}.parent = self
92         end
93 $   end
94 $ end
95     end
96
97     redef meth replace_child(old_child: PNode, new_child: PNode)
98     do
99         assert old_child != null
100 $ foreach {elem}
101 $   if @is_list
102         for i in [0.._n_@{name}.length[ do
103             if _n_@{name}[i] == old_child then
104                 if new_child != null then
105                     assert new_child isa @etype
106                     _n_@{name}[i] = new_child
107                     new_child.parent = self
108                 else
109                     _n_@{name}.remove_at(i)
110                 end
111                 return
112             end
113         end
114 $   else
115         if _n_@{name} == old_child then
116             if new_child != null then
117                 new_child.parent = self
118                 assert new_child isa @etype
119                 _n_@{name} = new_child
120             else
121                 _n_@{name} = null
122             end
123             return
124         end
125 $   end
126 $ end foreach
127     end
128
129     redef meth visit_all(v: Visitor)
130     do
131 $   foreach {elem}
132 $     if @is_list
133             for n in _n_@{name} do
134                 v.visit(n)
135             end
136 $     else
137         if _n_@{name} != null then
138             v.visit(_n_@{name})
139         end
140 $     end
141 $   end foreach
142     end
143
144     redef meth visit_all_reverse(v: Visitor)
145     do
146 $   foreach {elem}
147 $     if @is_list
148         do
149             var i = _n_@{name}.length
150             while i >= 0 do
151                 v.visit(_n_@{name}[i])
152                 i = i - 1
153             end
154         end
155 $     else
156         if _n_@{name} != null then
157             v.visit(_n_@{name})
158         end
159 $     end
160 $   end foreach
161     end
162 end
163 $ end foreach
164
165 redef class Start
166     init(
167         n_base: $baseprod,
168         n_eof: EOF)
169     do
170         _n_base = n_base
171         _n_eof = n_eof
172     end
173
174     redef meth replace_child(old_child: PNode, new_child: PNode)
175     do
176         assert old_child != null
177         if _n_base == old_child then
178             if new_child == null then
179             else
180                 new_child.parent = self
181                 assert new_child isa $baseprod
182                 _n_base = new_child
183             end
184             old_child.parent = null
185             return
186         end
187     end
188
189     redef meth visit_all(v: Visitor)
190     do
191         if _n_base != null then
192             v.visit(_n_base)
193         end
194     end
195
196     redef meth visit_all_reverse(v: Visitor)
197     do
198         if _n_base != null then
199             v.visit(_n_base)
200         end
201     end
202 end
203 $ end template