edist
[cdsspec-compiler.git] / grammer / backup-spec-compiler.jj
1 /* spec-compiler.jj Grammer definition for the specification */
2
3
4 /*
5         SPEC constructs:
6         Each construct should be embraced by /DOUBLE_STAR ... STAR/ annotation.
7         Within there, any line beginning with a "#" is a comment of the annotation.
8         Each constrcut should begin with @Begin and end with @End. Otherwise, the
9         annotation would be considered as normal comments of the source.
10         
11         a) Global construct
12         @Begin
13         @Options:
14                 # If LANG is not define, it's C++ by default. C does not support class
15                 # and template, so if it's defined as C, we should also have a explicit
16                 # entry point.
17                 LANG = C;
18         @Global_define:
19                 @DeclareVar:
20                 @InitVar:
21                 @DefineFunc:
22                 ...
23         @Interface_cluster:
24                 ...
25         @Happens-before:
26                 ...
27         @End
28         
29         b) Interface construct
30         @Begin
31         @Interface: ...
32         @Commit_point_set:
33                 IDENTIFIER | IDENTIFIER ...
34         @Condition: ... (Optional)
35         @HB_Condition:
36                 IDENTIFIER :: <C_CPP_Condition>
37         @HB_Condition: ...
38         @ID: ... (Optional, use default ID)
39         @Check: (Optional)
40                 ...
41         @Action: (Optional)
42                 # Type here must be a pointer
43                 @DefineVar: Type var1 = SomeExpression (Optional)
44                 @Code (Optional)
45                 ...
46         @Post_action: (Optional)
47         @Post_check: (Optional)
48         @End
49
50         c) Potential commit construct
51         @Begin
52         @Potential_commit_point_define: ...
53         @Label: ...
54         @End
55
56         d) Commit point define construct
57         @Begin
58         @Commit_point_define_check: ...
59         @Label: ...
60         @End
61         
62                 OR
63
64         @Begin
65         @Commit_point_define: ...
66         @Potential_commit_point_label: ...
67         @Label: ...
68         @End
69
70         e) Entry point construct
71         @Begin
72         @Entry_point
73         @End
74
75         f) Interface define construct
76         @Begin
77         @Interface_define: <Interface_Name>
78         @End
79 */
80
81
82
83 options {
84         STATIC = false;
85         JAVA_UNICODE_ESCAPE = true;
86 }
87
88 PARSER_BEGIN(SpecParser)
89 package edu.uci.eecs.specCompiler.grammerParser;
90
91 import java.io.FileInputStream;
92 import java.io.FileNotFoundException;
93 import java.io.InputStream;
94 import java.io.ByteArrayInputStream;
95 import java.util.ArrayList;
96 import java.util.HashMap;
97 import java.util.HashSet;
98
99 import edu.uci.eecs.specCompiler.specExtraction.Construct;
100 import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
101 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
102 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
103 import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
104 import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
105 import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
106 import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct;
107 import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct.DefineVar;
108 import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
109 import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
110 import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct;
111
112         public class SpecParser {
113                 public static void main(String[] argvs)
114                 throws ParseException, TokenMgrError {
115                         try {
116                                 FileInputStream fis = new FileInputStream("./grammer/spec.txt");
117                                 SpecParser parser = new SpecParser(fis);
118                                 //parser.Parse();
119                                 System.out.println("Parsing finished!");
120                                 ArrayList<String> typeParams = parser.FormalParamList();
121                         } catch (FileNotFoundException e) {
122                                 e.printStackTrace();
123                         }
124                 }
125         
126                 public static Construct parseSpec(String text)
127                 throws ParseException, TokenMgrError {
128                         InputStream input = new ByteArrayInputStream(text.getBytes());
129                         SpecParser parser = new SpecParser(input);
130                         return parser.Parse();
131                 }
132
133
134         }
135 PARSER_END(SpecParser)
136
137         "/*"}
138
139 < IN_COMMENT > SKIP : { <  ~[] > }
140
141 < IN_COMMENT > SKIP : {
142         "*/": DEFAULT
143 }
144
145 <IN_COMMENT> TOKEN : {
146         <A: "@A"> |
147         <B: "@B">
148 }
149
150 SKIP :
151 {
152         " "
153 |
154         "\n"
155 |
156         "\r"
157 |
158         "\r\n"
159 |
160         "\t"
161 |
162         // "#" comment for the specification
163         <"#" (~["\n", "\r"])* (["\n", "\r"])>
164 |
165         // "//" comment for the specification
166         <"//" (~["\n", "\r"])* (["\n", "\r"])>
167 }
168
169 <IN_COMMENT, DEFAULT> TOKEN :
170 {
171 /*   Above are specification-only tokens   */
172         <HEAD: "/**" : IN_COMMENT>
173 |
174         <TAIL: "*/" : DEFAULT>
175 |
176         <BEGIN: "@Begin">
177 |
178         <END: "@End">
179 |
180         <OPTIONS: "@Options:">
181 |
182         <GLOBAL_DEFINE: "@Global_define:">
183 |
184         <DECLARE_VAR: "@DeclareVar:">
185 |
186         <INIT_VAR: "@InitVar:">
187 |
188         <DEFINE_FUNC: "@DefineFunc:">
189 |
190         <INTERFACE_CLUSTER: "@Interface_cluster:">
191 |
192         <HAPPENS_BEFORE: "@Happens_before:">
193 |
194         <INTERFACE: "@Interface:">
195 |
196         <COMMIT_POINT_SET: "@Commit_point_set:">
197 |
198         <ENTRY_POINT: "@Entry_point">
199 |
200         <INTERFACE_DEFINE: "@Interface_define:">
201 |
202         <CONDITION: "@Condition:">
203 |
204         <HB_CONDITION: "@HB_condition:">
205 |
206         <ID: "@ID:">
207 |
208         <CHECK: "@Check:">
209 |
210         <ACTION: "@Action:">
211 |
212         <DEFINEVAR: "@DefineVar:">
213 |
214         <CODE: "@Code:">
215 |
216         <POST_ACTION: "@Post_action:">
217 |
218         <POST_CHECK: "@Post_check:">
219 |
220         <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
221 |
222         <LABEL: "@Label:">
223 |
224         <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
225 |
226         <COMMIT_POINT_DEFINE: "@Commit_point_define:">
227 |
228         <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
229
230
231 /*   Specification & C/C++ shared tokens   */
232
233 // Reserved keywords
234 |
235         <CONST: "const">
236 |
237         <STRUCT: "struct">
238 |
239         <TYPENAME: "typename">
240
241
242 |
243         <#DIGIT: ["0"-"9"]>
244 |
245         <#LETTER: ["a"-"z", "A"-"Z"]>
246 |
247         <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
248 |
249         <EQUALS: "=">
250 |
251         <OPEN_PAREN: "{">
252 |
253         <CLOSE_PAREN: "}">
254 |
255         <OPEN_BRACKET: "(">
256 |
257         <CLOSE_BRACKET: ")">
258 |
259         <HB_SYMBOL: "->">
260 |
261         <COMMA: ",">
262
263 |
264 /*   C/C++ only token*/
265         <DOT: ".">
266 |
267         <STAR: "*">
268 |
269         <NEGATE: "~">
270 |
271         <EXCLAMATION: "!">
272 |
273         <AND: "&">
274 |
275         <OR: "|">
276 |
277         <MOD: "%">
278 |
279         <PLUS: "+">
280 |
281         <PLUSPLUS: "++">
282 |
283         <MINUS: "-">
284 |
285         <MINUSMINUS: "--">
286 |
287         <DIVIDE: "/">
288 |
289         <BACKSLASH: "\\">
290 |
291         <LESS_THAN: "<">
292 |
293         <GREATER_THAN: ">">
294 |
295         <GREATER_EQUALS: ">=">
296 |
297         <LESS_EQUALS: "<=">
298 |
299         <LOGICAL_EQUALS: "==">
300 |
301         <NOT_EQUALS: "!=">
302 |
303         <LOGICAL_AND: "&&">
304 |
305         <LOGICAL_OR: "||">
306 |
307         <XOR: "^">
308 |
309         <QUESTION_MARK: "?">
310 |
311         <COLON: ":">
312 |
313         <DOUBLECOLON: "::">
314 |
315         <SEMI_COLON: ";">
316 |
317         <STRING_LITERAL:
318         "\""
319         ((~["\"","\\","\n","\r"])
320         | ("\\"
321                 ( ["n","t","b","r","f","\\","'","\""]
322                 | ["0"-"7"] ( ["0"-"7"] )?
323                 | ["0"-"3"] ["0"-"7"]
324                         ["0"-"7"]
325                 )
326                 )
327         )*
328         "\"">
329 |
330         <CHARACTER_LITERAL:
331         "'"
332         ((~["'","\\","\n","\r"])
333         | ("\\"
334                 (["n","t","b","r","f","\\","'","\""]
335                 | ["0"-"7"] ( ["0"-"7"] )?
336                 | ["0"-"3"] ["0"-"7"]
337                 ["0"-"7"]
338                 )
339                 )
340         )
341         "'">
342 |
343         < INTEGER_LITERAL:
344         <DECIMAL_LITERAL> (["l","L"])?
345       | <HEX_LITERAL> (["l","L"])?
346       | <OCTAL_LITERAL> (["l","L"])?>
347 |
348         < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
349 |
350         < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
351 |
352         < #OCTAL_LITERAL: "0" (["0"-"7"])* >
353 |
354         < FLOATING_POINT_LITERAL:
355         <DECIMAL_FLOATING_POINT_LITERAL>
356       | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
357 |
358         < #DECIMAL_FLOATING_POINT_LITERAL:
359         (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
360       | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
361       | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
362       | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
363 |
364         < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
365 |
366         < #HEXADECIMAL_FLOATING_POINT_LITERAL:
367         "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
368       | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
369 |
370         < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
371 }
372
373 String Type() :
374 {
375         String type;
376         String str;
377 }
378 {
379         { type = ""; }
380         ("const"
381         { type = "const"; }
382         )?
383         (("struct" { type = type + " struct"; })? 
384         (str = <IDENTIFIER>.image {
385                 if (!type.equals(""))
386                         type = type + " " + str;
387                 else
388                         type = str;
389         }))
390         ((str = "const".image {
391                 if (!type.equals(""))
392                         type = type + " " + str;
393                 else
394                         type = str;
395         }) |
396         (str = <STAR>.image {
397                 if (!type.equals(""))
398                         type = type + " " + str;
399                 else
400                         type = str;
401         }) |
402         (str = <AND>.image {
403                 if (!type.equals(""))
404                         type = type + " " + str;
405                 else
406                         type = str;
407         })
408         )*
409         {
410                 return type;
411         }
412 }
413
414 ArrayList<String> FormalParamList() :
415 {
416         ArrayList<String> typeParams;
417 }
418 {
419         {
420                 typeParams = new ArrayList<String>();
421         }
422         (TypeParam(typeParams) (<COMMA> TypeParam(typeParams))*)?
423         {
424                 System.out.println(typeParams);
425                 return typeParams;
426         }
427 }
428
429 void TypeParam(ArrayList<String> typeParams) :
430 {
431         String type, param;
432 }
433 {
434         (type = Type()) (param = <IDENTIFIER>.image)
435         {
436                 typeParams.add(type);
437                 typeParams.add(param);
438         }
439 }
440
441 Construct Parse() :
442 {
443         Construct res;  
444 }
445 {
446         (
447         LOOKAHEAD(3) res = Global_construct() |
448         LOOKAHEAD(3) res = Interface() |
449         LOOKAHEAD(3) res = Potential_commit_point_define() |
450         LOOKAHEAD(3) res = Commit_point_define() |
451         LOOKAHEAD(3) res = Commit_point_define_check() |
452         LOOKAHEAD(3) res = Entry_point() |
453         LOOKAHEAD(3) res = Interface_define()
454         )
455         <EOF>
456         {
457                 //System.out.println(res);
458                 return res;
459         }
460 }
461
462 GlobalConstruct Global_construct() :
463 {
464         GlobalConstruct res;
465         SequentialDefineSubConstruct code;
466         HashMap<String, String> options;
467         String key, value;
468 }
469 {
470         {
471                 res = null;
472                 options = new HashMap<String, String>();
473         }
474         <HEAD>
475                 <BEGIN> 
476                         (<OPTIONS>
477                                 ((key = <IDENTIFIER>.image)
478                                 <EQUALS>
479                                 (value = <IDENTIFIER>.image)
480                                 {
481                                         if (options.containsKey(key)) {
482                                                 throw new ParseException("Duplicate options!");
483                                         }
484                                         options.put(key, value);
485                                 }
486                                 <SEMI_COLON>
487                                 )*
488                         )?
489                         (code = Global_define())
490                         { res = new GlobalConstruct(code, options); }
491                         (Interface_clusters(res))?
492                         (Happens_before(res))?
493                 <END>
494         <TAIL>
495         {
496                 res.unfoldInterfaceCluster();
497                 return res;
498         }
499 }
500
501 String C_CPP_CODE() :
502 {
503         StringBuilder text;
504         Token t;
505 }
506 {
507         {
508                 text = new StringBuilder();
509                 t = new Token();
510         }
511         (
512         //LOOKAHEAD(2)
513         (
514         t = <CONST> | t = <STRUCT> |
515         t = <IDENTIFIER> | t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> |
516         t = <OPEN_BRACKET> | t = <CLOSE_BRACKET> | t = <HB_SYMBOL> | t = <COMMA> |
517         t = <DOT> | t = <STAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
518         t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
519         t = <LESS_THAN> | t = <GREATER_THAN> | t = <GREATER_EQUALS>     | t = <LESS_EQUALS> |
520         t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
521         t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
522         t = <SEMI_COLON> | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
523         t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL>
524         )
525         {
526                 text.append(t.image);
527                 if (t.image.equals(";") || t.image.equals("\\")
528                         || t.image.equals("{") || t.image.equals("}"))
529                         text.append("\n");
530                 else
531                         text.append(" ");
532         }
533         )+
534         {
535                 //System.out.println(text);
536                 return text.toString();
537         }
538 }
539
540 SequentialDefineSubConstruct Global_define() :
541 {
542         String declareVar, initVar, defineFunc;
543 }
544 {
545         {
546                 declareVar = "";
547                 initVar = "";
548                 defineFunc = "";
549         }
550         <GLOBAL_DEFINE>
551                 (<DECLARE_VAR> (declareVar = C_CPP_CODE()))?
552         (<INIT_VAR> (initVar = C_CPP_CODE()))?
553         (<DEFINE_FUNC> (defineFunc = C_CPP_CODE()))?
554         {
555                 SequentialDefineSubConstruct res = new SequentialDefineSubConstruct(declareVar, initVar, defineFunc);
556                 //System.out.println(res);
557                 return res;
558         }
559 }
560
561 ConditionalInterface Conditional_interface() :
562 {
563         String interfaceName, hbConditionLabel;
564 }
565 {
566         {
567                 hbConditionLabel = "";
568         }
569         interfaceName = <IDENTIFIER>.image (<OPEN_BRACKET> hbConditionLabel =
570         <IDENTIFIER>.image <CLOSE_BRACKET>)?
571         {
572                 return new ConditionalInterface(interfaceName, hbConditionLabel);
573         }
574 }
575
576 void Interface_cluster(GlobalConstruct inst) :
577 {
578         String clusterName;
579         ConditionalInterface condInterface;
580 }
581 {
582         (clusterName= <IDENTIFIER>.image)
583         <EQUALS> <OPEN_PAREN>
584                 (condInterface = Conditional_interface()
585                 { inst.addInterface2Cluster(clusterName, condInterface); } 
586                 )
587                 (<COMMA> condInterface = Conditional_interface()
588                 { inst.addInterface2Cluster(clusterName, condInterface); } 
589                 )*
590         <CLOSE_PAREN>
591 }
592
593 void Interface_clusters(GlobalConstruct inst) :
594 {}
595 {
596         <INTERFACE_CLUSTER> (Interface_cluster(inst))+
597 }
598
599 void Happens_before(GlobalConstruct inst) :
600 {
601         ConditionalInterface left, right;       
602 }
603 {
604         <HAPPENS_BEFORE> 
605         (
606         left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
607         { inst.addHBCondition(left, right); }
608         )+
609 }
610
611 InterfaceConstruct Interface() :
612 {
613         InterfaceConstruct res;
614         String interfaceName, condition, idCode, check, postAction,
615                 postCheck, commitPoint, hbLabel, hbCondition;
616         ActionSubConstruct action;
617         ArrayList<String> commitPointSet;
618         HashMap<String, String> hbConditions;
619 }
620 {
621         {
622                 res = null;
623                 action = null;
624                 condition = "";
625                 idCode = "";
626                 check = "";
627                 postAction = "";
628                 postCheck = "";
629                 commitPointSet = new ArrayList<String>();
630                 hbConditions = new HashMap<String, String>();
631         }
632         <HEAD> 
633                 <BEGIN>
634                         <INTERFACE> (interfaceName = <IDENTIFIER>.image)
635                         <COMMIT_POINT_SET>
636                                 (commitPoint = <IDENTIFIER>.image
637                                 { commitPointSet.add(commitPoint); }
638                                 )
639                                 (<OR>
640                                         (commitPoint = <IDENTIFIER>.image)
641                                         {
642                                                 if (commitPointSet.contains(commitPoint)) {
643                                                         throw new ParseException(interfaceName + " has" +
644                                                                 "duplicate commit point labels");
645                                                 }
646                                                 commitPointSet.add(commitPoint);
647                                         }
648                                 )*
649
650                         (<CONDITION> (condition = C_CPP_CODE()))?
651                         (
652                                 <HB_CONDITION>
653                                 (hbLabel = <IDENTIFIER>.image)
654                                 (hbCondition = C_CPP_CODE())
655                                 {
656                                         if (hbConditions.containsKey(hbLabel)) {
657                                                 throw new ParseException(interfaceName + " has" +
658                                                         "duplicate happens-before condtion labels");
659                                         }
660                                         hbConditions.put(hbLabel, hbCondition);
661                                 }
662                         )*
663                         (<ID> (idCode = C_CPP_CODE()))?
664                         (<CHECK> (check = C_CPP_CODE()))?
665                         (action = Action())?
666                         (<POST_ACTION> (postAction = C_CPP_CODE()))?
667                         (<POST_CHECK> (postCheck = C_CPP_CODE()))?
668                 <END>
669         <TAIL>
670         {
671                 res = new InterfaceConstruct(interfaceName, commitPointSet, condition,
672                         hbConditions, idCode, check, action, postAction, postCheck);
673                 return res;
674         }
675 }
676
677 ActionSubConstruct Action() :
678 {
679         String type, name, expr, defineVarStr, code;
680         ArrayList<DefineVar> defineVars;
681 }
682 {
683         {
684                 defineVars = new ArrayList<DefineVar>();
685                 code = "";
686         }
687         <ACTION>
688         (
689                 (
690                 (<DEFINEVAR> (defineVarStr = C_CPP_CODE()) 
691                 {
692                         int eqIdx = defineVarStr.indexOf('=');
693                         int typeEnd = defineVarStr.lastIndexOf(' ', eqIdx - 2);
694                         type = defineVarStr.substring(0, typeEnd);
695                         name = defineVarStr.substring(typeEnd + 1, eqIdx - 1);
696                         expr = defineVarStr.substring(eqIdx + 2);
697                         DefineVar defineVar = new DefineVar(type, name, expr);
698                         defineVars.add(defineVar);
699                 })*  (<CODE> (code = C_CPP_CODE()))? ) 
700         )
701         
702         {
703                 ActionSubConstruct res = new ActionSubConstruct(defineVars, code);
704                 return res;
705         }
706 }
707
708 PotentialCPDefineConstruct Potential_commit_point_define() :
709 {
710         PotentialCPDefineConstruct res;
711         String label, condition;
712 }
713 {
714
715         { res = null; }
716         <HEAD> 
717                 <BEGIN>
718                         <POTENTIAL_COMMIT_POINT_DEFINE> (condition = C_CPP_CODE())
719                         <LABEL> (label = <IDENTIFIER>.image)
720                 <END>
721         <TAIL>
722         {
723                 res = new PotentialCPDefineConstruct(label, condition); 
724                 return res;
725         }
726 }
727
728
729 CPDefineConstruct Commit_point_define() :
730 {
731         CPDefineConstruct res;
732         String label, potentialCPLabel, condition;
733 }
734 {
735
736         { res = null; }
737         <HEAD> 
738                 <BEGIN>
739                         <COMMIT_POINT_DEFINE> (condition = C_CPP_CODE())
740                         <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
741                         <LABEL> (label = <IDENTIFIER>.image)
742                 <END>
743         <TAIL>
744         {
745                 res = new CPDefineConstruct(label, potentialCPLabel, condition);
746                 return res;
747         }
748 }
749
750
751 CPDefineCheckConstruct Commit_point_define_check() :
752 {
753         CPDefineCheckConstruct res;     
754         String label, condition;
755 }
756 {
757
758         { res = null; }
759         <HEAD> 
760                 <BEGIN> 
761                         <COMMIT_POINT_DEFINE_CHECK> (condition = C_CPP_CODE())
762                         <LABEL> (label = <IDENTIFIER>.image)
763                 <END>
764         <TAIL>
765         {
766                 res = new CPDefineCheckConstruct(label, condition);
767                 return res;
768         }
769 }
770
771 EntryPointConstruct Entry_point() :
772 {}
773 {
774
775         <HEAD> 
776                 <BEGIN> 
777                         <ENTRY_POINT>
778                 <END>
779         <TAIL>
780         {
781                 return new EntryPointConstruct();
782         }
783 }
784
785 InterfaceDefineConstruct Interface_define() :
786 {
787         String name;    
788 }
789 {
790         <HEAD>
791                 <BEGIN>
792                         <INTERFACE_DEFINE> (name = <IDENTIFIER>.image)
793                 <END>
794         <TAIL>
795         {
796                 return new InterfaceDefineConstruct(name);
797         }
798 }
799
800