1: doctype public "-//IDN etl.sf.net//ETL//Grammar 0.2";
2: /// This abstract grammar defines common control flow constructs
3: /// for imperative programming languages. Functional programming
4: /// languages would likely need completely different set of constructs.
5: /// Note that grammar does not dictate style of definitions in the
6: /// language.
7: ///
8: /// The contructs are mostly rip off Java and C# languages. However
9: /// they are somewhat tweaked to conform more to ETL style. There is no
10: /// "goto" statement in grammar. It might be added in separate grammar.
11: /// However grammar contains common loop continue/break variation of goto and
12: /// it also contains "continue case" for implementing fall through in switch.
13: ///
14: /// This grammar demostrates how to create a reusable module that can be used in
15: /// other grammars.
16: grammar abstract net.sf.etl.samples.ej.CommonControlFlow {
17: namespace c = "http://etl.sf.net/2006/samples/ej/0.1";
18:
19:
20:
21: context abstract CommonControlFlow_Commons {
22: /// This is an extension point that should be overriden by
23: /// contexts that include this context. It should reference
24: /// a generic expression. The definition must be redefined
25: /// in including grammars.
26: ///
27: /// The definition should refer to top level expression
28: def CommonControlFlow_GenericExpression {
29:
30: };
31: };
32:
33: /// This context contains common control flow constructs for
34: /// imperative programming languages. Note that context is abstract
35: /// and it cannot be used directly. The context has to be specialized
36: /// in order to be useful.
37: context abstract CommonControlFlow {
38: include CommonControlFlow_Commons;
39: import CommonControlFlow_SwitchContent = CommonControlFlow_SwitchContent;
40:
41:
42:
43:
44:
45: /// Common label fragment
46: def CommonControlFlow_LabelFragment {
47: let label = identifier wrapper c:Label.name;
48: };
49:
50: /// This extension point may be overriden by context that define
51: /// conditional expression in different way than generic expression.
52: /// For example, it is possible to specify that condition should of
53: /// level that has lowever priority than assignment level.
54: def CommonControlFlow_ConditionalExpression {
55: ref(CommonControlFlow_GenericExpression);
56: };
57:
58: /// This extension point may be overriden by context that define
59: /// conditional expression in different way than generic expression.
60: /// For example, it is possible to specify that condition should of
61: /// level that has lowever priority than assignment level.
62: def CommonControlFlow_ConditionFragment {
63: brackets () {
64: let condition = ref(CommonControlFlow_ConditionalExpression);
65: };
66: };
67:
68: /// This is a pattern that can be matched by exception. The definition
69: /// must be redefined in including grammars.
70: def CommonControlFlow_ParameterPattern {
71: };
72:
73: /// This is an utility definition of block body.
74: def CommonControlFlow_Body {
75: let body = ref(CommonControlFlow_BlockFragment);
76: };
77:
78: /// Redefine block fragment to refer to itself
79: def CommonControlFlow_BlockFragment {
80: object c:MethodBlock {
81: let content += block;
82: };
83: };
84:
85: /// This is a generic expression statement. The expression
86: /// executed in such way is supposed to have side effects.
87: /// For example, it can update local variable or invoke system
88: /// call.
89: statement ExpressionStatement {
90: object c:ExpressionStatement {
91: let expression = ref(CommonControlFlow_GenericExpression);
92: };
93: };
94:
95:
96:
97: /// Classical conditional statement almost only irregularity is that
98: /// "else if" is written as "elseif".
99: statement IfStatement {
100: object c:IfStatement {
101: let ifThenPart += {
102: section if {
103: object c:IfThenPart {
104: ref(CommonControlFlow_ConditionFragment);
105: ref(CommonControlFlow_Body);
106: };
107: };
108: section elseif {
109: object c:IfThenPart {
110: ref(CommonControlFlow_ConditionFragment);
111: ref(CommonControlFlow_Body);
112: };
113: }*;
114: };
115: section else {
116: let elsePart = ref(CommonControlFlow_BlockFragment);
117: }?;
118: };
119: };
120:
121: statement SwitchStatement {
122: object c:SwitchStatement {
123: section switch {
124: ref(CommonControlFlow_LabelFragment)?;
125: brackets () { let value = ref(CommonControlFlow_GenericExpression);};
126: let parts += block(CommonControlFlow_SwitchContent);
127: };
128: };
129: };
130:
131: statement WhileStatement {
132: object c:WhileStatement {
133: section while {
134: ref(CommonControlFlow_LabelFragment)?;
135: ref(CommonControlFlow_ConditionFragment);
136: ref(CommonControlFlow_Body);
137: };
138: };
139: };
140:
141: statement DoWhileStatement {
142: object c:DoWhileStatement {
143: section do{
144: ref(CommonControlFlow_LabelFragment)?;
145: ref(CommonControlFlow_Body);
146: };
147: section while{
148: ref(CommonControlFlow_ConditionFragment);
149: };
150: };
151: };
152:
153: statement BreakStatement {
154: object c:BreakStatement{
155: section break {
156: ref(CommonControlFlow_LabelFragment)?;
157: };
158: };
159: };
160:
161: def CommonControlFlow_ContinueSwitchRef {
162: section case {
163: {
164: let caseValue = ref(CommonControlFlow_GenericExpression);
165: } | {
166: let defaultLabel = object c:SwitchDefaultPartRef {
167: section default {};
168: };
169: };
170: };
171: };
172:
173: statement ContinueStatement {
174: object c:ContinueStatement{
175: section continue {
176: {
177: ref(CommonControlFlow_LabelFragment);
178: ref(CommonControlFlow_ContinueSwitchRef)?;
179: } | {
180: ref(CommonControlFlow_ContinueSwitchRef)?;
181: };
182: };
183: };
184: };
185:
186: statement ReturnStatement {
187: object c:ReturnStatement {
188: section return {
189: {
190: let value = ref(CommonControlFlow_GenericExpression);
191: }?;
192: };
193: };
194: };
195:
196: statement ThrowStatement {
197: object c:ThrowStatement {
198: section throw {
199: let exception = ref(CommonControlFlow_GenericExpression);
200: };
201: };
202: };
203: statement TryStatement {
204: object c:TryStatement {
205: section try {
206: ref(CommonControlFlow_Body);
207: };
208: {
209: section catch {
210: let catchPart += object c:CatchPart {
211: let specification = brackets ( ) {
212: ref(CommonControlFlow_ParameterPattern);
213: };
214: ref(CommonControlFlow_Body);
215: };
216: }+;
217: section finally {
218: let finallyPart = ref(CommonControlFlow_BlockFragment);
219: }?;
220: } | {
221: section finally {
222: let finallyPart = ref(CommonControlFlow_BlockFragment);
223: };
224: };
225: };
226: };
227: statement ForeachStatement {
228: object c:ForeachStatement {
229: section foreach {
230: ref(CommonControlFlow_LabelFragment)?;
231: brackets ( ) {
232: let parameter = ref(CommonControlFlow_ParameterPattern);
233: section in {
234: let collection = ref(CommonControlFlow_GenericExpression);
235: } | {
236: section from {
237: let initial = ref(CommonControlFlow_GenericExpression);
238: };
239: section to {
240: let limit = ref(CommonControlFlow_GenericExpression);
241: };
242: };
243: };
244: ref(CommonControlFlow_Body);
245: };
246: };
247: };
248:
249: statement MethodBlock {
250: ref(CommonControlFlow_BlockFragment);
251: };
252:
253: };
254:
255: context abstract CommonControlFlow_SwitchContent {
256: include CommonControlFlow_Commons;
257: import CommonControlFlow = CommonControlFlow;
258:
259: def CommonControlFlow_Body {
260: let body = object c:MethodBlock {
261: let content += block(CommonControlFlow);
262: };
263: };
264:
265: statement SwitchCasePart {
266: object c:SwitchCasePart {
267: section case {
268: let values += list , {ref(CommonControlFlow_GenericExpression);};
269: ref(CommonControlFlow_Body);
270: };
271: };
272: };
273: statement SwitchDefaultPart {
274: object c:SwitchDefaultPart {
275: section default {
276: ref(CommonControlFlow_Body);
277: };
278: };
279: };
280:
281: };
282: };