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