1options {
2	language="Cpp";
3}
4
5/**
6 *  This is a complete parser for the IDL language as defined
7 *  by the CORBA 2.0 specification.  It will allow those who
8 *  need an IDL parser to get up-and-running very quickly.
9 *  Though IDL's syntax is very similar to C++, it is also
10 *  much simpler, due in large part to the fact that it is
11 *  a declarative-only language.
12 *
13 *  Some things that are not included are: Symbol table construction
14 *  (it is not necessary for parsing, btw) and preprocessing (for
15 *  IDL compiler #pragma directives). You can use just about any
16 *  C or C++ preprocessor, but there is an interesting semantic
17 *  issue if you are going to generate code: In C, #include is
18 *  a literal include, in IDL, #include is more like Java's import:
19 *  It adds definitions to the scope of the parse, but included
20 *  definitions are not generated.
21 *
22 *  Jim Coker, jcoker@magelang.com
23 */
24class IDLParser extends Parser;
25options {
26	exportVocab=IDL;
27}
28
29specification
30	:   (definition)+
31  	;
32
33definition
34	:   (   type_dcl SEMI!
35	    |   const_dcl SEMI!
36 	    |   except_dcl SEMI!
37	    |   interf SEMI!
38	    |   module SEMI!
39	    )
40	;
41
42module
43	:    "module"
44	     identifier
45 	     LCURLY d:definition_list RCURLY
46	;
47
48definition_list
49	:   (definition)+
50	;
51
52interf
53	:   "interface"
54	    identifier
55	    inheritance_spec
56 	    (interface_body)?
57	;
58
59interface_body
60	:   LCURLY! (export_spec)*  RCURLY!
61	;
62
63export_spec
64	:   (   type_dcl SEMI
65	    |   const_dcl SEMI
66	    |   except_dcl SEMI
67	    |   attr_dcl SEMI
68	    |   op_dcl SEMI
69            )
70	;
71
72inheritance_spec
73	:   COLON scoped_name_list
74	|
75	;
76
77scoped_name_list
78	:    scoped_name (COMMA scoped_name)*
79	;
80
81scoped_name
82	:   opt_scope_op identifier (SCOPEOP identifier)*
83	;
84
85opt_scope_op
86	:   SCOPEOP
87	|
88	;
89
90const_dcl
91	:   "const" const_type identifier ASSIGN const_exp
92	;
93
94const_type
95	:   integer_type
96	|   char_type
97	|   boolean_type
98	|   floating_pt_type
99	|   string_type
100	|   scoped_name
101	;
102
103/*   EXPRESSIONS   */
104
105const_exp
106	:   or_expr
107	;
108
109or_expr
110	:   xor_expr
111	     (   or_op
112		xor_expr
113             )*
114	;
115
116or_op
117	:    OR
118	;
119
120xor_expr
121	:    and_expr
122	     (  xor_op
123		and_expr
124             )*
125	;
126
127xor_op
128	:    XOR
129	;
130
131and_expr
132	:    shift_expr
133	     (  and_op
134		shift_expr
135             )*
136	;
137
138and_op
139	:    AND
140	;
141
142shift_expr
143	:    add_expr
144	     (  shift_op
145	     	add_expr
146	     )*
147	;
148
149shift_op
150	:    LSHIFT
151	|    RSHIFT
152	;
153
154add_expr
155	:    mult_expr
156	     (  add_op
157		mult_expr
158             )*
159	;
160
161add_op
162	:    PLUS
163	|    MINUS
164	;
165
166mult_expr
167	:   unary_expr
168	     (  mult_op
169		unary_expr
170             )*
171	;
172
173mult_op
174	:    STAR
175	|    DIV
176	|    MOD
177	;
178
179unary_expr
180	:    unary_operator primary_expr
181	|    primary_expr
182	;
183
184unary_operator
185	:   MINUS
186	|   PLUS
187	|   TILDE
188	;
189
190// Node of type TPrimaryExp serves to avoid inf. recursion on tree parse
191primary_expr
192	:   scoped_name
193	|   literal
194	|   LPAREN const_exp RPAREN
195	;
196
197literal
198	:   integer_literal
199	|   string_literal
200	|   character_literal
201	|   floating_pt_literal
202	|   boolean_literal
203	;
204
205boolean_literal
206	:   "TRUE"
207	|   "FALSE"
208	;
209
210positive_int_const
211	:    const_exp
212	;
213
214type_dcl
215	:   "typedef" type_declarator
216	|   struct_type
217	|   union_type
218	|   enum_type
219	|
220	|   "native" simple_declarator
221	;
222
223type_declarator
224	:   type_spec declarators
225	;
226
227type_spec
228	:   simple_type_spec
229	|   constr_type_spec
230	;
231
232simple_type_spec
233	:   base_type_spec
234	|   template_type_spec
235	|   scoped_name
236	;
237
238base_type_spec
239	:   integer_type
240	|   char_type
241	|   boolean_type
242	|   floating_pt_type
243	|   "octet"
244	|   "any"
245	;
246
247integer_type
248	:  ("unsigned")? ("short" | "long")
249	;
250
251char_type
252	:   "char"
253	;
254
255floating_pt_type
256	:   "float"
257	|   "double"
258	;
259
260boolean_type
261        :   "boolean"
262	;
263
264template_type_spec
265	:   sequence_type
266	|   string_type
267	;
268
269constr_type_spec
270	:   struct_type
271	|   union_type
272	|   enum_type
273	;
274
275declarators
276	:   declarator (COMMA declarator)*
277	;
278
279declarator
280	:   identifier opt_fixed_array_size
281	;
282
283opt_fixed_array_size
284	:	(fixed_array_size)*
285	;
286
287simple_declarator
288	:   identifier
289	;
290
291struct_type
292	:   "struct"
293	    identifier
294	    LCURLY member_list RCURLY
295	;
296
297member_list
298	:   (member)+
299	;
300
301member
302	:   type_spec declarators SEMI
303	;
304
305union_type
306	:   "union"
307 	    identifier
308	         "switch" LPAREN switch_type_spec RPAREN
309                  LCURLY switch_body RCURLY
310	;
311
312switch_type_spec
313	:   integer_type
314	|   char_type
315	|   boolean_type
316	|   enum_type
317	|   scoped_name
318	;
319
320switch_body
321	:   case_stmt_list
322	;
323
324case_stmt_list
325	:  (case_stmt)+
326	;
327
328case_stmt
329	:   case_label_list element_spec SEMI
330	;
331
332case_label_list
333	:   (case_label)+
334	;
335
336case_label
337	:   "case" const_exp COLON
338	|   "default" COLON
339	;
340
341element_spec
342	:   type_spec declarator
343	;
344
345enum_type
346	:   "enum" identifier LCURLY enumerator_list RCURLY
347	;
348
349enumerator_list
350	:    enumerator (COMMA enumerator)*
351	;
352
353enumerator
354	:   identifier
355	;
356
357sequence_type
358	:   "sequence"
359	     LT_ simple_type_spec opt_pos_int GT
360	;
361
362opt_pos_int
363	:    (COMMA positive_int_const)?
364	;
365
366string_type
367	:   "string" opt_pos_int_br
368	;
369
370opt_pos_int_br
371	:    (LT_ positive_int_const GT)?
372	;
373
374fixed_array_size
375	:   LBRACK positive_int_const RBRACK
376	;
377
378attr_dcl
379	:   ("readonly")?
380            "attribute" param_type_spec
381            simple_declarator_list
382	;
383
384simple_declarator_list
385	:     simple_declarator (COMMA simple_declarator)*
386	;
387
388except_dcl
389	:   "exception"
390	    identifier
391	     LCURLY opt_member_list RCURLY
392	;
393
394opt_member_list
395	:    (member)*
396	;
397
398op_dcl
399	:   op_attribute op_type_spec
400            identifier
401	    parameter_dcls
402            opt_raises_expr c:opt_context_expr
403	;
404
405opt_raises_expr
406	:   (raises_expr)?
407	;
408
409opt_context_expr
410	:   (context_expr)?
411	;
412
413op_attribute
414	:   "oneway"
415	|
416	;
417
418op_type_spec
419	:   param_type_spec
420	|   "void"
421	;
422
423parameter_dcls
424	:  LPAREN (param_dcl_list)? RPAREN!
425	;
426
427param_dcl_list
428	:    param_dcl (COMMA param_dcl)*
429	;
430
431param_dcl
432	:   param_attribute param_type_spec simple_declarator
433	;
434
435param_attribute
436	:   "in"
437	|   "out"
438	|   "inout"
439	;
440
441raises_expr
442	:   "raises" LPAREN scoped_name_list RPAREN
443	;
444
445context_expr
446	:   "context" LPAREN string_literal_list RPAREN
447	;
448
449string_literal_list
450	:    string_literal (COMMA! string_literal)*
451	;
452
453param_type_spec
454	:   base_type_spec
455	|   string_type
456	|   scoped_name
457	;
458
459integer_literal
460 	:   INT
461	|   OCTAL
462	|   HEX
463        ;
464
465string_literal
466	:  (STRING_LITERAL)+
467	;
468
469character_literal
470	:   CHAR_LITERAL
471	;
472
473floating_pt_literal
474	:   f:FLOAT
475     	;
476
477identifier
478	:   IDENT
479  	;
480
481/* IDL LEXICAL RULES  */
482class IDLLexer extends Lexer;
483options {
484	exportVocab=IDL;
485	k=4;
486}
487
488SEMI
489options {
490  paraphrase = ";";
491}
492	:	';'
493	;
494
495QUESTION
496options {
497  paraphrase = "?";
498}
499	:	'?'
500	;
501
502LPAREN
503options {
504  paraphrase = "(";
505}
506	:	'('
507	;
508
509RPAREN
510options {
511  paraphrase = ")";
512}
513	:	')'
514	;
515
516LBRACK
517options {
518  paraphrase = "[";
519}
520	:	'['
521	;
522
523RBRACK
524options {
525  paraphrase = "]";
526}
527	:	']'
528	;
529
530LCURLY
531options {
532  paraphrase = "{";
533}
534	:	'{'
535	;
536
537RCURLY
538options {
539  paraphrase = "}";
540}
541	:	'}'
542	;
543
544OR
545options {
546  paraphrase = "|";
547}
548	:	'|'
549	;
550
551XOR
552options {
553  paraphrase = "^";
554}
555	:	'^'
556	;
557
558AND
559options {
560  paraphrase = "&";
561}
562	:	'&'
563	;
564
565COLON
566options {
567  paraphrase = ":";
568}
569	:	':'
570	;
571
572COMMA
573options {
574  paraphrase = ",";
575}
576	:	','
577	;
578
579DOT
580options {
581  paraphrase = ".";
582}
583	:	'.'
584	;
585
586ASSIGN
587options {
588  paraphrase = "=";
589}
590	:	'='
591	;
592
593NOT
594options {
595  paraphrase = "!";
596}
597	:	'!'
598	;
599
600LT_
601options {
602  paraphrase = "<";
603}
604	:	'<'
605	;
606
607LSHIFT
608options {
609  paraphrase = "<<";
610}
611	: "<<"
612	;
613
614GT
615options {
616  paraphrase = ">";
617}
618	:	'>'
619	;
620
621RSHIFT
622options {
623  paraphrase = ">>";
624}
625	: ">>"
626	;
627
628DIV
629options {
630  paraphrase = "/";
631}
632	:	'/'
633	;
634
635PLUS
636options {
637  paraphrase = "+";
638}
639	:	'+'
640	;
641
642MINUS
643options {
644  paraphrase = "-";
645}
646	:	'-'
647	;
648
649TILDE
650options {
651  paraphrase = "~";
652}
653	:	'~'
654	;
655
656STAR
657options {
658  paraphrase = "*";
659}
660	:	'*'
661	;
662
663MOD
664options {
665  paraphrase = "%";
666}
667	:	'%'
668	;
669
670SCOPEOP
671options {
672  paraphrase = "::";
673}
674	:  	"::"
675	;
676
677WS_
678options {
679  paraphrase = "white space";
680}
681	:	(' '
682	|	'\t'
683	|	'\n'  { newline(); }
684	|	'\r')
685		{ $setType(ANTLR_USE_NAMESPACE(antlr)Token::SKIP); }
686	;
687
688PREPROC_DIRECTIVE
689options {
690  paraphrase = "a preprocessor directive";
691}
692
693	:
694	'#'
695	(~'\n')* '\n'
696	{ $setType(ANTLR_USE_NAMESPACE(antlr)Token::SKIP); }
697	;
698
699SL_COMMENT
700options {
701  paraphrase = "a comment";
702}
703
704	:
705	"//"
706	(~'\n')* '\n'
707	{ $setType(ANTLR_USE_NAMESPACE(antlr)Token::SKIP); newline(); }
708	;
709
710ML_COMMENT
711options {
712  paraphrase = "a comment";
713}
714	:
715	"/*"
716	(
717			STRING_LITERAL
718		|	CHAR_LITERAL
719		|	'\n' { newline(); }
720		|	'*' ~'/'
721		|	~'*'
722	)*
723	"*/"
724	{ $setType(ANTLR_USE_NAMESPACE(antlr)Token::SKIP);  }
725	;
726
727CHAR_LITERAL
728options {
729  paraphrase = "a character literal";
730}
731	:
732	'\''
733	( ESC | ~'\'' )
734	'\''
735	;
736
737STRING_LITERAL
738options {
739  paraphrase = "a string literal";
740}
741	:
742	'"'
743	(ESC|~'"')*
744	'"'
745	;
746
747protected
748ESC
749options {
750  paraphrase = "an escape sequence";
751}
752	:	'\\'
753		(	'n'
754		|	't'
755		|	'v'
756		|	'b'
757		|	'r'
758		|	'f'
759		|	'a'
760		|	'\\'
761		|	'?'
762		|	'\''
763		|	'"'
764		|	('0' | '1' | '2' | '3')
765			(
766				/* Since a digit can occur in a string literal,
767				 * which can follow an ESC reference, ANTLR
768				 * does not know if you want to match the digit
769				 * here (greedy) or in string literal.
770				 * The same applies for the next two decisions
771				 * with the warnWhenFollowAmbig option.
772				 */
773				options {
774					warnWhenFollowAmbig = false;
775				}
776			:	OCTDIGIT
777				(
778					options {
779						warnWhenFollowAmbig = false;
780					}
781				:	OCTDIGIT
782				)?
783			)?
784		|   'x' HEXDIGIT
785			(
786				options {
787					warnWhenFollowAmbig = false;
788				}
789			:	HEXDIGIT
790			)?
791		)
792	;
793
794protected
795VOCAB
796options {
797  paraphrase = "an escaped character value";
798}
799	:	'\3'..'\377'
800	;
801
802protected
803DIGIT
804options {
805  paraphrase = "a digit";
806}
807	:	'0'..'9'
808	;
809
810protected
811OCTDIGIT
812options {
813  paraphrase = "an octal digit";
814}
815	:	'0'..'7'
816	;
817
818protected
819HEXDIGIT
820options {
821  paraphrase = "a hexadecimal digit";
822}
823	:	('0'..'9' | 'a'..'f' | 'A'..'F')
824	;
825
826/* octal literals are detected by checkOctal */
827
828HEX
829options {
830  paraphrase = "a hexadecimal value value";
831}
832
833	:    ("0x" | "0X") (HEXDIGIT)+
834	;
835
836INT
837options {
838  paraphrase = "an integer value";
839}
840	:    (DIGIT)+                  // base-10
841             (  '.' (DIGIT)*                      	{$setType(FLOAT);}
842	         (('e' | 'E') ('+' | '-')? (DIGIT)+)?
843	     |   ('e' | 'E') ('+' | '-')? (DIGIT)+   	{$setType(FLOAT);}
844             )?
845	;
846
847FLOAT
848options {
849  paraphrase = "an floating point value";
850}
851
852	:    '.' (DIGIT)+ (('e' | 'E') ('+' | '-')? (DIGIT)+)?
853     	;
854
855IDENT
856options {
857  testLiterals = true;
858  paraphrase = "an identifer";
859}
860
861	:	('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
862	;
863