1: doctype public "-//IDN etl.sf.net//ETL//Grammar 0.2";
2:
3: /// This is a grammar for EJ language. The language is targeted to cover
4: /// all features of Java language in the way that is similar to one used
5: /// in Java.
6: ///
7: /// Note that the goal of this sample was to get a sample that is as close
8: /// to Java as possible within ETL. However is the task is to get a good language
9: /// for JVM, a better languages are possible. For example taking more functional
10: /// approach is possible allowing constructs like:
11: /// "let a := {let b:= Math.sin(Math.PI/3); 2*b*(b+1);};"
12: ///
13: /// So do not use this source as a sample of the langauge design. It has
14: /// known quality issues in this area.
15: grammar net.sf.etl.samples.ej.EJ {
16: include "CommonControlFlow.g.etl";
17: include "CommonOperators.g.etl";
18: namespace ej = "http://etl.sf.net/2006/samples/ej/0.1";
19:
20: /// This context contains common definitions that are shared
21: /// between statements and expressions.
22: context abstract Base {
23: import Expressions = Expressions;
24: import TypeExpressions = TypeExpressions;
25: import ClassContents = ClassContents;
26: import MethodContent = MethodContent;
27: import NameExpressions = NameExpressions;
28:
29: def NameFragment {
30: object ej:Identifier {
31: {
32: let value = identifier;
33: } | {
34: let quotedValue = string(quote="`");
35: };
36: };
37: };
38:
39: def AttributesDef {
40: let attributeSets += {
41: object ej:AttributeSet {
42: section @ {
43: brackets [] {
44: let attributes += list , {
45: expression(Expressions,priority=100);
46: };
47: };
48: };
49: };
50: };
51: };
52:
53: def TemplateBounds {
54: {
55: {
56: section super {
57: let superToTypes += list & {
58: expression(TypeExpressions);
59: };
60: };
61: } | {
62: section extends {
63: let extendedTypes += list & {
64: expression(TypeExpressions);
65: };
66: };
67: };
68: }?;
69: };
70:
71: def ClassBlockDef {
72: object ej:ClassBlock {
73: let content += block(ClassContents);
74: };
75: };
76:
77: def TemplateParameters {
78: brackets [ ] {
79: let templateParameters += list , {
80: object ej:TemplateParameter {
81: let name = expression(NameExpressions);
82: ref(TemplateBounds);
83: };
84: };
85: };
86: };
87:
88:
89: def NameDefinitionFragment {
90: let classifier = expression(TypeExpressions);
91: let name = expression(NameExpressions);
92: };
93:
94: def ParameterFragment {
95: object ej:Parameter {
96: ref(AttributesDef)?;
97: modifiers wrapper ej:Modifier.value {
98: let finalModifier = modifier final;
99: };
100: ref(NameDefinitionFragment);
101: };
102: };
103:
104: def VariableSetFragment {
105: let classifier = expression(TypeExpressions);
106: let variables += list , {
107: object ej:Variable {
108: let name = expression(NameExpressions);
109: section = {
110: let initialValue = expression(Expressions);
111: }?;
112: };
113: };
114: };
115:
116: def MethodBlockFragment {
117: object ej:MethodBlock {
118: let content += block(MethodContent);
119: };
120: };
121:
122:
123: };
124:
125: /// This context contains common definitions used in statements across
126: /// all contexts.
127: context abstract BaseStatements {
128: include Base;
129:
130: attributes Attributes {
131: ref(AttributesDef);
132: };
133:
134: documentation Documentation {
135: let documentation += doclines wrapper ej:DocumentationLine.text;
136: };
137:
138:
139:
140:
141: };
142:
143: context NameExpressions {
144: include Base;
145:
146: composite Identifier(f) {
147: ref(NameFragment);
148: };
149:
150: };
151:
152: context PackageNameExpressions {
153: include NameExpressions;
154:
155: simple AccessOp(yfx,100,.) {
156: object ej:AccessOp {
157: let accessed = left;
158: let feature=right;
159: };
160: };
161: };
162:
163: context TypeExpressions {
164: include PackageNameExpressions;
165:
166: composite ApplySquareOp(yf,100) {
167: object ej:ApplySquareOp {
168: let functor = left;
169: let args += brackets [ ] {
170: list , {
171: expression;
172: };
173: };
174: };
175: };
176:
177: composite ArrayType(f) {
178: object ej:PrimitiveType {
179: let name = token(array);
180: };
181: };
182:
183: composite BooleanType(f) {
184: object ej:PrimitiveType {
185: let name = token(boolean);
186: };
187: };
188:
189: composite ByteType(f) {
190: object ej:PrimitiveType {
191: let name = token(byte);
192: };
193: };
194:
195: composite ShortType(f) {
196: object ej:PrimitiveType {
197: let name = token(short);
198: };
199: };
200:
201: composite IntType(f) {
202: object ej:PrimitiveType {
203: let name = token(int);
204: };
205: };
206:
207: composite LongType(f) {
208: object ej:PrimitiveType {
209: let name = token(long);
210: };
211: };
212:
213: composite CharType(f) {
214: object ej:PrimitiveType {
215: let name = token(char);
216: };
217: };
218:
219: composite FloatType(f) {
220: object ej:PrimitiveType {
221: let name = token(float);
222: };
223: };
224:
225: composite DoubleType(f) {
226: object ej:PrimitiveType {
227: let name = token(double);
228: };
229: };
230:
231: composite VoidType(f) {
232: object ej:PrimitiveType {
233: let name = token(void);
234: };
235: };
236:
237: composite WildcardType(f) {
238: object ej:WildcardType {
239: section ? {
240: ref(TemplateBounds);
241: };
242: };
243: };
244: };
245:
246: context Expressions {
247: include TypeExpressions;
248: include CommonOperators;
249: import ClassContents = ClassContents;
250: import TypeExpressions = TypeExpressions;
251:
252: composite ThisReference(f) {
253: object ej:ThisReference {
254: let name = token(this);
255: };
256: };
257:
258: composite SuperReference(f) {
259: object ej:SuperReference {
260: let name = token(super);
261: };
262: };
263: composite NullReference(f) {
264: object ej:NullReference {
265: let value = token(null);
266: };
267: };
268: composite BooleanLiteral(f) {
269: object ej:BooleanLiteral {
270: let value = token(true) | token(false);
271: };
272: };
273: composite StringLiteral(f) {
274: object ej:StringLiteral {
275: let value = string(quote="\"");
276: };
277: };
278:
279: /// Note that constraint that literal can contain only one
280: /// character is not not enforced at grammar level.
281: composite CharacterLiteral(f) {
282: object ej:CharacterLiteral {
283: let value = string(quote="'");
284: };
285: };
286:
287: composite IntegerLiteral(f) {
288: object ej:IntegerLiteral {
289: let value = integer;
290: };
291: };
292:
293: composite LongIntegerLiteral(f) {
294: object ej:LongIntegerLiteral {
295: let value = integer(suffix="l") | integer(suffix="L");
296: };
297: };
298:
299: composite DoubleLiteral(f) {
300: object ej:DoubleLiteral {
301: let value =
302: integer(suffix="d") | integer(suffix="D") |
303: float |
304: float(suffix="D") | float(suffix="d");
305: };
306: };
307:
308: composite FloatLiteral(f) {
309: object ej:FloatLiteral {
310: let value =
311: integer(suffix="f") | integer(suffix="F") |
312: float(suffix="f") | float(suffix="F");
313: };
314: };
315:
316: def ArrayConstructorFragment {
317: object ej:ArrayConstructor {
318: brackets [ ] {
319: let values += list , {
320: expression;
321: }?;
322: };
323: };
324: };
325:
326: composite ArrayConstructor(f) {
327: ref(ArrayConstructorFragment);
328: };
329:
330: composite NewOp(f) {
331: object ej:NewOp {
332: section new {
333: let classifier = expression(TypeExpressions,priority=100);
334: {
335: let arrayConstructor = section with {
336: ref(ArrayConstructorFragment);
337: };
338: } | {
339: let args += brackets ( ) {
340: list , {
341: expression;
342: }?;
343: };
344: let classBody = ref(ClassBlockDef)?;
345: };
346: };
347: };
348: };
349:
350: composite IdentityOp(f) {
351: object ej:IdentityOp {
352: brackets ( ) {
353: let value = expression;
354: };
355: };
356: };
357:
358: composite ApplyRound(yf,100) {
359: object ej:ApplyRoundOp {
360: let functor = left;
361: let args += brackets ( ) {
362: list , {
363: expression;
364: }?;
365: };
366: };
367: };
368:
369: /// Note it is possible to enforce more constraints by
370: /// using composite operator.
371: simple CastOp(xfx,300,as) {
372: object ej:CastOp { let value = left; let classifier = right; };
373: };
374:
375: simple InstanceOfOp(xfx,700,instanceof) {
376: object ej:InstanceOfOp { let value = left; let classifier =right; };
377: };
378:
379:
380: simple AssignmentOp(xfy,1500,=) {
381: object ej:AssignmentOp { let leftHandSide = left; let value =right; };
382: };
383:
384: simple PlusAssignmentOp(xfy,1500,+=) {
385: object ej:PlusAssignmentOp { let leftHandSide = left; let value =right; };
386: };
387:
388: simple MinusAssignmentOp(xfy,1500,-=) {
389: object ej:MinusAssignmentOp { let leftHandSide = left; let value =right; };
390: };
391:
392: simple MultiplyAssignmentOp(xfy,1500,*=) {
393: object ej:MultiplyAssignmentOp { let leftHandSide = left; let value =right; };
394: };
395:
396: simple DivideAssignmentOp(xfy,1500,/=) {
397: object ej:DivideAssignmentOp { let leftHandSide = left; let value =right; };
398: };
399:
400: simple BitwiseAndAssignmentOp(xfy,1500,&=) {
401: object ej:BitwiseAndAssignmentOp { let leftHandSide = left; let value =right; };
402: };
403:
404: simple BitwiseOrAssignmentOp(xfy,1500,|=) {
405: object ej:BitwiseOrAssignmentOp { let leftHandSide = left; let value =right; };
406: };
407:
408: simple BitwiseXorAssignmentOp(xfy,1500,^=) {
409: object ej:BitwiseXorAssignmentOp { let leftHandSide = left; let value =right; };
410: };
411:
412: simple RemainderAssignmentOp (xfy,1500,%=) {
413: object ej:RemainderAssignmentOp { let leftHandSide = left; let value =right; };
414: };
415:
416: simple LeftShiftAssignmentOp(xfy,1500,<<=) {
417: object ej:LeftShiftAssignmentOp { let leftHandSide = left; let value =right; };
418: };
419:
420: simple RightShiftAssignmentOp(xfy,1500,>>=) {
421: object ej:RightShiftAssignmentOp { let leftHandSide = left; let value =right; };
422: };
423:
424: simple ZeroExtensionRightShiftAssignmentOp(xfy,1500,>>>=) {
425: object ej:ZeroExtensionRightShiftAssignmentOp { let leftHandSide = left; let value =right; };
426: };
427:
428: simple PrefixIncrementOp(fy,200,++) {
429: object ej:PrefixIncrementOp { let value =right; };
430: };
431:
432: simple PostfixIncrementOp(yf,300,++) {
433: object ej:PostfixIncrementOp { let value = left; };
434: };
435:
436: simple PrefixDecrementOp(fy,200,--) {
437: object ej:PrefixDecrementOp { let value =right; };
438: };
439:
440: simple PostfixDecrementOp(yf,300,--) {
441: object ej:PostfixDecrementOp { let value = left; };
442: };
443: };
444:
445: context abstract MethodContentCommons {
446: include BaseStatements;
447: include CommonControlFlow_Commons;
448: /// Redefine generic expression from common control flow
449: def CommonControlFlow_GenericExpression {
450: expression(Expressions);
451: };
452: };
453:
454: context MethodContent {
455: include InnerClassifiers wrapper ej:MethodClassifier.classifier;
456: include MethodContentCommons;
457: include CommonControlFlow;
458: import CommonControlFlow_SwitchContent = MethodContent_SwitchContent;
459:
460: /// Redefine fragment to refer to itself
461: def MethodBlockFragment {
462: object ej:MethodBlock {
463: let content += block;
464: };
465: };
466:
467: /// Redefine exception pattern from common control flow
468: def CommonControlFlow_ParameterPattern {
469: ref(ParameterFragment);
470: };
471:
472: /// This a blank statement
473: statement EmptyStatement {
474: object ej:EmptyStatement {
475: };
476: };
477:
478: statement ForStatement {
479: object ej:ForStatement {
480: section for{
481: ref(CommonControlFlow_LabelFragment)?;
482: brackets ( ) {
483: {
484: let initVariableDeclaration = object ej:LocalVarStatement{
485: ref(LocalVariablesStatementFragment);
486: };
487: } | {
488: let initExpressions += expression(Expressions);
489: } | {};
490: section : {
491: let condition=expression(Expressions)?;
492: };
493: section : {
494: let updateExpressions += list , {
495: expression(Expressions);
496: }?;
497: };
498: };
499: ref(CommonControlFlow_Body);
500: };
501: };
502: };
503:
504: statement LocalVarStatement {
505: object ej:LocalVarStatement{
506: ref(LocalVariablesStatementFragment);
507: };
508: };
509:
510:
511: def LocalVariablesStatementFragment {
512: section var {
513: modifiers wrapper ej:Modifier.value {
514: let finalModifier = modifier final;
515: };
516: ref(VariableSetFragment);
517: };
518: };
519:
520:
521: statement SynchronizedStatement {
522: object ej:SynchronizedStatement {
523: section synchronized {
524: brackets ( ) {let value=expression(Expressions);};
525: ref(CommonControlFlow_Body);
526: };
527: };
528: };
529:
530:
531: statement AssertStatement {
532: object ej:AssertStatement {
533: section assert {
534: let test = expression(Expressions);
535: };
536: section : {
537: let message = expression(Expressions);
538: }?;
539: };
540: };
541: };
542:
543: context MethodContent_SwitchContent {
544: include MethodContentCommons;
545: include CommonControlFlow_SwitchContent;
546: import CommonControlFlow = MethodContent;
547:
548: };
549:
550: context abstract ClassifierContent {
551: include BaseStatements;
552: import NameExpressions = NameExpressions;
553: include InnerClassifiers wrapper ej:InnerClassifier.classifier;
554:
555: def MethodSignatureFragment {
556: let returnType = expression(TypeExpressions);
557: ref(ConstructorSignatureFragment);
558: };
559: def ConstructorSignatureFragment {
560: let name = ref(NameFragment);
561: brackets() {
562: list , {
563: let parameters += ref(ParameterFragment);
564: }?;
565: };
566: section throws {
567: list , { let exceptions += expression(TypeExpressions);};
568: }?;
569: };
570: };
571:
572: context ClassContents {
573: include ClassifierContent;
574: statement MethodStatement {
575: object ej:MethodStatement {
576: section to {
577: ref(TemplateParameters)?;
578: modifiers wrapper ej:Modifier.value {
579: let visibilityModifier = modifier public;
580: let visibilityModifier = modifier protected;
581: let visibilityModifier = modifier private;
582: let staticModifier = modifier static;
583: let strictfpModifier = modifier strictfp;
584: let abstractModifier = modifier abstract;
585: let finalModifier = modifier final;
586: let synchronizedModifier = modifier syncrhonized;
587: };
588: ref(MethodSignatureFragment);
589: };
590: let body = ref(MethodBlockFragment)?;
591:
592: };
593: };
594: statement FieldStatement {
595: object ej:FieldStatement {
596: section var {
597: modifiers wrapper ej:Modifier.value {
598: let visibilityModifier = modifier public;
599: let visibilityModifier = modifier protected;
600: let visibilityModifier = modifier private;
601: let staticModifier = modifier static;
602: let abstractModifier = modifier abstract;
603: let finalModifier = modifier final;
604: let transientModifier = modifier transient;
605: let volatileModifier = modifier volatile;
606: };
607: ref(VariableSetFragment);
608: };
609: };
610: };
611:
612: statement InitStatement {
613: object ej:InitStatement {
614: let body = ref(MethodBlockFragment);
615: };
616: };
617:
618: statement StaticInitStatement {
619: object ej:StaticInitStatement {
620: section static {
621: let body = ref(MethodBlockFragment);
622: };
623: };
624: };
625:
626: statement ConstructorStatement {
627: object ej:ConstructorStatement {
628: section maker {
629: modifiers wrapper ej:Modifier.value {
630: let visibilityModifier = modifier public;
631: let visibilityModifier = modifier protected;
632: let visibilityModifier = modifier private;
633: };
634: ref(ConstructorSignatureFragment);
635: };
636: let body = ref(MethodBlockFragment);
637: };
638: };
639: };
640:
641: context InterfaceContents {
642: include ClassifierContent;
643: statement MethodStatement {
644: object ej:MethodStatement {
645: section to {
646: modifiers wrapper ej:Modifier.value {
647: let visibilityModifier = modifier public;
648: let abstractModifier = modifier abstract;
649: };
650: ref(MethodSignatureFragment);
651: };
652: };
653: };
654:
655: statement FieldStatement {
656: object ej:FieldStatement {
657: section var {
658: modifiers wrapper ej:Modifier.value {
659: let visibilityModifier = modifier public;
660: let staticModifier = modifier static;
661: let finalModifier = modifier final;
662: };
663: ref(VariableSetFragment);
664: };
665: };
666: };
667: };
668:
669: context AttributeContents {
670: include BaseStatements;
671: statement FieldStatement {
672: object ej:FieldStatement {
673: section var {
674: ref(VariableSetFragment);
675: };
676: };
677: };
678: };
679:
680: context EnumerationContents {
681: include ClassContents;
682:
683: statement LiteralStatement {
684: object ej:EnumLiteral {
685: section literal {
686: let name = expression(NameExpressions);
687: brackets ( ) {
688: let args += list , {
689: expression(Expressions);
690: };
691: }?;
692: {
693: let body = ref(ClassBlockDef);
694: }?;
695: };
696: };
697: };
698:
699:
700: };
701:
702:
703: context abstract InnerClassifiers {
704: include BaseStatements;
705: import EnumerationContents = EnumerationContents;
706: import ClassContents = ClassContents;
707: import InterfaceContents = InterfaceContents;
708:
709: def ClassModifiersDef {
710: modifiers wrapper ej:Modifier.value {
711: let visibilityModifier = modifier public;
712: let visibilityModifier = modifier protected;
713: let visibilityModifier = modifier private;
714:
715: let staticModifier = modifier static;
716: let strictfpModifier = modifier strictfp;
717: let abstractModifier = modifier abstract;
718: let finalModifier = modifier final;
719: let synchronizedModifier = modifier syncrhonized;
720: };
721: };
722:
723: statement ClassStatement {
724: object ej:ClassStatement {
725: section class {
726: ref(ClassModifiersDef);
727: let name = ref(NameFragment);
728: ref(TemplateParameters)?;
729: };
730: section extends {
731: let extendedType = expression(TypeExpressions);
732: }?;
733: section implements {
734: let implementedTypes += list , {expression(TypeExpressions);};
735: }?;
736: let contents += block(ClassContents);
737: };
738: };
739:
740:
741: statement InterfaceStatement {
742: object ej:InterfaceStatement {
743: section interface {
744: modifiers wrapper ej:Modifier.value {
745: let visibilityModifier = modifier public;
746: };
747: let name = ref(NameFragment);
748: ref(TemplateParameters)?;
749: };
750: section extends {
751: let extendedTypes += list , {expression(TypeExpressions);};
752: }?;
753: let contents += block(InterfaceContents);
754: };
755: };
756: statement EnumStatement {
757: object ej:EnumStatement {
758: section enum {
759: ref(ClassModifiersDef);
760: let name = ref(NameFragment);
761: };
762: let contents += block(EnumerationContents);
763: };
764: };
765:
766: };
767:
768: context AllClassifiers {
769: include InnerClassifiers;
770: import AttributeContents = AttributeContents;
771: statement AttributeDefinition {
772: object ej:AttributeDefinition {
773: section attribute {
774: modifiers wrapper ej:Modifier.value {
775: let visibilityModifier = modifier public;
776: };
777: let name = ref(NameFragment);
778: };
779: let contents += block(AttributeContents);
780: };
781: };
782: };
783:
784: context default TopLevel {
785: include AllClassifiers wrapper ej:TopLevelClassifier.classifier;
786: import PackageNameExpressions = PackageNameExpressions;
787: /// This is an package statement.
788: /// <usage>
789: /// package java.awt;
790: /// </usage>
791: statement PackageStatement {
792: object ej:PackageStatement {
793: section package {
794: let name = expression(PackageNameExpressions);
795: };
796: };
797: };
798: /// This is an import statement.
799: /// <usage>
800: /// import java.util.List;
801: /// import all static java.lang.Math;
802: /// import all java.rmi;
803: /// </usage>
804: statement ImportStatement {
805: object ej:ImportStatement {
806: section import {
807: modifiers wrapper ej:Modifier.value {
808: let allModifier = modifier all;
809: let staticModifier = modifier static;
810: };
811: let importedPackage = expression(PackageNameExpressions);
812: };
813: };
814: };
815: };
816: };