1 #!/usr/bin/ruby 2 # encoding: utf-8 3 4 require 'antlr3/test/functional' 5 6 class TestASTViaRewriteRules < ANTLR3::Test::Functional 7 8 def parse( grammar, rule, input, expect_errors = false ) 9 @grammar = inline_grammar( grammar ) 10 compile_and_load @grammar 11 grammar_module = self.class.const_get( @grammar.name ) 12 13 grammar_module::Lexer.send( :include, ANTLR3::Test::CollectErrors ) 14 grammar_module::Lexer.send( :include, ANTLR3::Test::CaptureOutput ) 15 grammar_module::Parser.send( :include, ANTLR3::Test::CollectErrors ) 16 grammar_module::Parser.send( :include, ANTLR3::Test::CaptureOutput ) 17 18 lexer = grammar_module::Lexer.new( input ) 19 parser = grammar_module::Parser.new( lexer ) 20 21 r = parser.send( rule ) 22 parser.reported_errors.should be_empty unless expect_errors 23 result = '' 24 25 unless r.nil? 26 result += r.result if r.respond_to?( :result ) 27 result += r.tree.inspect if r.tree 28 end 29 return( expect_errors ? [ result, parser.reported_errors ] : result ) 30 end 31 32 def tree_parse( grammar, tree_grammar, rule, tree_rule, input ) 33 @grammar = inline_grammar( grammar ) 34 @tree_grammar = inline_grammar( tree_grammar ) 35 compile_and_load @grammar 36 compile_and_load @tree_grammar 37 38 grammar_module = self.class.const_get( @grammar.name ) 39 tree_grammar_module = self.class.const_get( @tree_grammar.name ) 40 41 grammar_module::Lexer.send( :include, ANTLR3::Test::CollectErrors ) 42 grammar_module::Lexer.send( :include, ANTLR3::Test::CaptureOutput ) 43 grammar_module::Parser.send( :include, ANTLR3::Test::CollectErrors ) 44 grammar_module::Parser.send( :include, ANTLR3::Test::CaptureOutput ) 45 tree_grammar_module::TreeParser.send( :include, ANTLR3::Test::CollectErrors ) 46 tree_grammar_module::TreeParser.send( :include, ANTLR3::Test::CaptureOutput ) 47 48 lexer = grammar_module::Lexer.new( input ) 49 parser = grammar.module::Parser.new( lexer ) 50 r = parser.send( rule ) 51 nodes = ANTLR3::CommonTreeNodeStream( r.tree ) 52 nodes.token_stream = parser.input 53 walker = tree_grammar_module::TreeParser.new( nodes ) 54 r = walker.send( tree_rule ) 55 56 return( r ? r.tree.inspect : '' ) 57 end 58 59 example "delete" do 60 result = parse( <<-'END', :a, 'abc 34' ) 61 grammar Delete; 62 options {language=Ruby;output=AST;} 63 a : ID INT -> ; 64 ID : 'a'..'z'+ ; 65 INT : '0'..'9'+; 66 WS : (' '|'\n') {$channel=HIDDEN;} ; 67 END 68 result.should == '' 69 end 70 71 72 example "single token" do 73 result = parse( <<-'END', :a, 'abc' ) 74 grammar SingleToken; 75 options {language=Ruby;output=AST;} 76 a : ID -> ID; 77 ID : 'a'..'z'+ ; 78 INT : '0'..'9'+; 79 WS : (' '|'\n') {$channel=HIDDEN;} ; 80 81 END 82 result.should == 'abc' 83 end 84 85 86 example "single token to new node" do 87 result = parse( <<-'END', :a, 'abc' ) 88 grammar SingleTokenToNewNode; 89 options {language=Ruby;output=AST;} 90 a : ID -> ID["x"]; 91 ID : 'a'..'z'+ ; 92 INT : '0'..'9'+; 93 WS : (' '|'\n') {$channel=HIDDEN;} ; 94 95 END 96 result.should == 'x' 97 end 98 99 100 example "single token to new node root" do 101 result = parse( <<-'END', :a, 'abc' ) 102 grammar SingleTokenToNewNodeRoot; 103 options {language=Ruby;output=AST;} 104 a : ID -> ^(ID["x"] INT); 105 ID : 'a'..'z'+ ; 106 INT : '0'..'9'+; 107 WS : (' '|'\n') {$channel=HIDDEN;} ; 108 109 END 110 result.should == '(x INT)' 111 end 112 113 114 example "single token to new node2" do 115 result = parse( <<-'END', :a, 'abc' ) 116 grammar SingleTokenToNewNode2; 117 options {language=Ruby;output=AST;} 118 a : ID -> ID[ ]; 119 ID : 'a'..'z'+ ; 120 INT : '0'..'9'+; 121 WS : (' '|'\n') {$channel=HIDDEN;} ; 122 END 123 result.should == 'ID' 124 end 125 126 127 example "single char literal" do 128 result = parse( <<-'END', :a, 'c' ) 129 grammar SingleCharLiteral; 130 options {language=Ruby;output=AST;} 131 a : 'c' -> 'c'; 132 ID : 'a'..'z'+ ; 133 INT : '0'..'9'+; 134 WS : (' '|'\n') {$channel=HIDDEN;} ; 135 136 END 137 result.should == 'c' 138 end 139 140 141 example "single string literal" do 142 result = parse( <<-'END', :a, 'ick' ) 143 grammar SingleStringLiteral; 144 options {language=Ruby;output=AST;} 145 a : 'ick' -> 'ick'; 146 ID : 'a'..'z'+ ; 147 INT : '0'..'9'+; 148 WS : (' '|'\n') {$channel=HIDDEN;} ; 149 150 END 151 result.should == 'ick' 152 end 153 154 155 example "single rule" do 156 result = parse( <<-'END', :a, 'abc' ) 157 grammar SingleRule; 158 options {language=Ruby;output=AST;} 159 a : b -> b; 160 b : ID ; 161 ID : 'a'..'z'+ ; 162 INT : '0'..'9'+; 163 WS : (' '|'\n') {$channel=HIDDEN;} ; 164 165 END 166 result.should == 'abc' 167 end 168 169 170 example "reorder tokens" do 171 result = parse( <<-'END', :a, 'abc 34' ) 172 grammar ReorderTokens; 173 options {language=Ruby;output=AST;} 174 a : ID INT -> INT ID; 175 ID : 'a'..'z'+ ; 176 INT : '0'..'9'+; 177 WS : (' '|'\n') {$channel=HIDDEN;} ; 178 179 END 180 result.should == '34 abc' 181 end 182 183 184 example "reorder token and rule" do 185 result = parse( <<-'END', :a, 'abc 34' ) 186 grammar ReorderTokenAndRule; 187 options {language=Ruby;output=AST;} 188 a : b INT -> INT b; 189 b : ID ; 190 ID : 'a'..'z'+ ; 191 INT : '0'..'9'+; 192 WS : (' '|'\n') {$channel=HIDDEN;} ; 193 194 END 195 result.should == '34 abc' 196 end 197 198 199 example "token tree" do 200 result = parse( <<-'END', :a, 'abc 34' ) 201 grammar TokenTree; 202 options {language=Ruby;output=AST;} 203 a : ID INT -> ^(INT ID); 204 ID : 'a'..'z'+ ; 205 INT : '0'..'9'+; 206 WS : (' '|'\n') {$channel=HIDDEN;} ; 207 208 END 209 result.should == '(34 abc)' 210 end 211 212 213 example "token tree after other stuff" do 214 result = parse( <<-'END', :a, 'void abc 34' ) 215 grammar TokenTreeAfterOtherStuff; 216 options {language=Ruby;output=AST;} 217 a : 'void' ID INT -> 'void' ^(INT ID); 218 ID : 'a'..'z'+ ; 219 INT : '0'..'9'+; 220 WS : (' '|'\n') {$channel=HIDDEN;} ; 221 222 END 223 result.should == 'void (34 abc)' 224 end 225 226 227 example "nested token tree with outer loop" do 228 result = parse( <<-'END', :a, 'a 1 b 2' ) 229 grammar NestedTokenTreeWithOuterLoop; 230 options {language=Ruby;output=AST;} 231 tokens {DUH;} 232 a : ID INT ID INT -> ^( DUH ID ^( DUH INT) )+ ; 233 ID : 'a'..'z'+ ; 234 INT : '0'..'9'+; 235 WS : (' '|'\n') {$channel=HIDDEN;} ; 236 237 END 238 result.should == '(DUH a (DUH 1)) (DUH b (DUH 2))' 239 end 240 241 242 example "optional single token" do 243 result = parse( <<-'END', :a, 'abc' ) 244 grammar OptionalSingleToken; 245 options {language=Ruby;output=AST;} 246 a : ID -> ID? ; 247 ID : 'a'..'z'+ ; 248 INT : '0'..'9'+; 249 WS : (' '|'\n') {$channel=HIDDEN;} ; 250 251 END 252 result.should == 'abc' 253 end 254 255 256 example "closure single token" do 257 result = parse( <<-'END', :a, 'a b' ) 258 grammar ClosureSingleToken; 259 options {language=Ruby;output=AST;} 260 a : ID ID -> ID* ; 261 ID : 'a'..'z'+ ; 262 INT : '0'..'9'+; 263 WS : (' '|'\n') {$channel=HIDDEN;} ; 264 265 END 266 result.should == 'a b' 267 end 268 269 270 example "positive closure single token" do 271 result = parse( <<-'END', :a, 'a b' ) 272 grammar PositiveClosureSingleToken; 273 options {language=Ruby;output=AST;} 274 a : ID ID -> ID+ ; 275 ID : 'a'..'z'+ ; 276 INT : '0'..'9'+; 277 WS : (' '|'\n') {$channel=HIDDEN;} ; 278 279 END 280 result.should == 'a b' 281 end 282 283 284 example "optional single rule" do 285 result = parse( <<-'END', :a, 'abc' ) 286 grammar OptionalSingleRule; 287 options {language=Ruby;output=AST;} 288 a : b -> b?; 289 b : ID ; 290 ID : 'a'..'z'+ ; 291 INT : '0'..'9'+; 292 WS : (' '|'\n') {$channel=HIDDEN;} ; 293 294 END 295 result.should == 'abc' 296 end 297 298 299 example "closure single rule" do 300 result = parse( <<-'END', :a, 'a b' ) 301 grammar ClosureSingleRule; 302 options {language=Ruby;output=AST;} 303 a : b b -> b*; 304 b : ID ; 305 ID : 'a'..'z'+ ; 306 INT : '0'..'9'+; 307 WS : (' '|'\n') {$channel=HIDDEN;} ; 308 309 END 310 result.should == 'a b' 311 end 312 313 314 example "closure of label" do 315 result = parse( <<-'END', :a, 'a b' ) 316 grammar ClosureOfLabel; 317 options {language=Ruby;output=AST;} 318 a : x+=b x+=b -> $x*; 319 b : ID ; 320 ID : 'a'..'z'+ ; 321 INT : '0'..'9'+; 322 WS : (' '|'\n') {$channel=HIDDEN;} ; 323 324 END 325 result.should == 'a b' 326 end 327 328 329 example "optional label no list label" do 330 result = parse( <<-'END', :a, 'a' ) 331 grammar OptionalLabelNoListLabel; 332 options {language=Ruby;output=AST;} 333 a : (x=ID)? -> $x?; 334 ID : 'a'..'z'+ ; 335 INT : '0'..'9'+; 336 WS : (' '|'\n') {$channel=HIDDEN;} ; 337 338 END 339 result.should == 'a' 340 end 341 342 343 example "positive closure single rule" do 344 result = parse( <<-'END', :a, 'a b' ) 345 grammar PositiveClosureSingleRule; 346 options {language=Ruby;output=AST;} 347 a : b b -> b+; 348 b : ID ; 349 ID : 'a'..'z'+ ; 350 INT : '0'..'9'+; 351 WS : (' '|'\n') {$channel=HIDDEN;} ; 352 353 END 354 result.should == 'a b' 355 end 356 357 358 example "single predicate t" do 359 result = parse( <<-'END', :a, 'abc' ) 360 grammar SinglePredicateT; 361 options {language=Ruby;output=AST;} 362 a : ID -> {true}? ID -> ; 363 ID : 'a'..'z'+ ; 364 INT : '0'..'9'+; 365 WS : (' '|'\n') {$channel=HIDDEN;} ; 366 367 END 368 result.should == 'abc' 369 end 370 371 372 example "single predicate f" do 373 result = parse( <<-'END', :a, 'abc' ) 374 grammar SinglePredicateF; 375 options {language=Ruby;output=AST;} 376 a : ID -> {false}? ID -> ; 377 ID : 'a'..'z'+ ; 378 INT : '0'..'9'+; 379 WS : (' '|'\n') {$channel=HIDDEN;} ; 380 381 END 382 result.should == '' 383 end 384 385 386 example "multiple predicate" do 387 result = parse( <<-'END', :a, 'a 2' ) 388 grammar MultiplePredicate; 389 options {language=Ruby;output=AST;} 390 a : ID INT -> {false}? ID 391 -> {true}? INT 392 -> 393 ; 394 ID : 'a'..'z'+ ; 395 INT : '0'..'9'+; 396 WS : (' '|'\n') {$channel=HIDDEN;} ; 397 398 END 399 result.should == '2' 400 end 401 402 403 example "multiple predicate trees" do 404 result = parse( <<-'END', :a, 'a 2' ) 405 grammar MultiplePredicateTrees; 406 options {language=Ruby;output=AST;} 407 a : ID INT -> {false}? ^(ID INT) 408 -> {true}? ^(INT ID) 409 -> ID 410 ; 411 ID : 'a'..'z'+ ; 412 INT : '0'..'9'+; 413 WS : (' '|'\n') {$channel=HIDDEN;} ; 414 415 END 416 result.should == '(2 a)' 417 end 418 419 420 example "simple tree" do 421 result = parse( <<-'END', :a, '-34' ) 422 grammar SimpleTree; 423 options {language=Ruby;output=AST;} 424 a : op INT -> ^(op INT); 425 op : '+'|'-' ; 426 ID : 'a'..'z'+ ; 427 INT : '0'..'9'+; 428 WS : (' '|'\n') {$channel=HIDDEN;} ; 429 430 END 431 result.should == '(- 34)' 432 end 433 434 435 example "simple tree2" do 436 result = parse( <<-'END', :a, '+ 34' ) 437 grammar SimpleTree2; 438 options {language=Ruby;output=AST;} 439 a : op INT -> ^(INT op); 440 op : '+'|'-' ; 441 ID : 'a'..'z'+ ; 442 INT : '0'..'9'+; 443 WS : (' '|'\n') {$channel=HIDDEN;} ; 444 445 END 446 result.should == '(34 +)' 447 end 448 449 450 example "nested trees" do 451 result = parse( <<-'END', :a, 'var a:int; b:float;' ) 452 grammar NestedTrees; 453 options {language=Ruby;output=AST;} 454 a : 'var' (ID ':' type ';')+ -> ^('var' ^(':' ID type)+) ; 455 type : 'int' | 'float' ; 456 ID : 'a'..'z'+ ; 457 INT : '0'..'9'+; 458 WS : (' '|'\n') {$channel=HIDDEN;} ; 459 460 END 461 result.should == '(var (: a int) (: b float))' 462 end 463 464 465 example "imaginary token copy" do 466 result = parse( <<-'END', :a, 'a,b,c' ) 467 grammar ImaginaryTokenCopy; 468 options {language=Ruby;output=AST;} 469 tokens {VAR;} 470 a : ID (',' ID)*-> ^(VAR ID)+ ; 471 type : 'int' | 'float' ; 472 ID : 'a'..'z'+ ; 473 INT : '0'..'9'+; 474 WS : (' '|'\n') {$channel=HIDDEN;} ; 475 476 END 477 result.should == '(VAR a) (VAR b) (VAR c)' 478 end 479 480 481 example "token unreferenced on left but defined" do 482 result = parse( <<-'END', :a, 'a' ) 483 grammar TokenUnreferencedOnLeftButDefined; 484 options {language=Ruby;output=AST;} 485 tokens {VAR;} 486 a : b -> ID ; 487 b : ID ; 488 ID : 'a'..'z'+ ; 489 INT : '0'..'9'+; 490 WS : (' '|'\n') {$channel=HIDDEN;} ; 491 492 END 493 result.should == 'ID' 494 end 495 496 497 example "imaginary token copy set text" do 498 result = parse( <<-'END', :a, 'a,b,c' ) 499 grammar ImaginaryTokenCopySetText; 500 options {language=Ruby;output=AST;} 501 tokens {VAR;} 502 a : ID (',' ID)*-> ^(VAR["var"] ID)+ ; 503 type : 'int' | 'float' ; 504 ID : 'a'..'z'+ ; 505 INT : '0'..'9'+; 506 WS : (' '|'\n') {$channel=HIDDEN;} ; 507 508 END 509 result.should == '(var a) (var b) (var c)' 510 end 511 512 513 example "imaginary token no copy from token" do 514 result = parse( <<-'END', :a, '{a b c}' ) 515 grammar ImaginaryTokenNoCopyFromToken; 516 options {language=Ruby;output=AST;} 517 tokens {BLOCK;} 518 a : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ; 519 type : 'int' | 'float' ; 520 ID : 'a'..'z'+ ; 521 INT : '0'..'9'+; 522 WS : (' '|'\n') {$channel=HIDDEN;} ; 523 524 END 525 result.should == '({ a b c)' 526 end 527 528 529 example "imaginary token no copy from token set text" do 530 result = parse( <<-'END', :a, '{a b c}' ) 531 grammar ImaginaryTokenNoCopyFromTokenSetText; 532 options {language=Ruby;output=AST;} 533 tokens {BLOCK;} 534 a : lc='{' ID+ '}' -> ^(BLOCK[$lc,"block"] ID+) ; 535 type : 'int' | 'float' ; 536 ID : 'a'..'z'+ ; 537 INT : '0'..'9'+; 538 WS : (' '|'\n') {$channel=HIDDEN;} ; 539 540 END 541 result.should == '(block a b c)' 542 end 543 544 545 example "mixed rewrite and auto ast" do 546 result = parse( <<-'END', :a, 'a 1 2' ) 547 grammar MixedRewriteAndAutoAST; 548 options {language=Ruby;output=AST;} 549 tokens {BLOCK;} 550 a : b b^ ; // 2nd b matches only an INT; can make it root 551 b : ID INT -> INT ID 552 | INT 553 ; 554 ID : 'a'..'z'+ ; 555 INT : '0'..'9'+; 556 WS : (' '|'\n') {$channel=HIDDEN;} ; 557 END 558 result.should == '(2 1 a)' 559 end 560 561 562 example "subrule with rewrite" do 563 result = parse( <<-'END', :a, 'a 1 2 3' ) 564 grammar SubruleWithRewrite; 565 options {language=Ruby;output=AST;} 566 tokens {BLOCK;} 567 a : b b ; 568 b : (ID INT -> INT ID | INT INT -> INT+ ) 569 ; 570 ID : 'a'..'z'+ ; 571 INT : '0'..'9'+; 572 WS : (' '|'\n') {$channel=HIDDEN;} ; 573 574 END 575 result.should == '1 a 2 3' 576 end 577 578 579 example "subrule with rewrite2" do 580 result = parse( <<-'END', :a, 'int a; int b=3;' ) 581 grammar SubruleWithRewrite2; 582 options {language=Ruby;output=AST;} 583 tokens {TYPE;} 584 a : b b ; 585 b : 'int' 586 ( ID -> ^(TYPE 'int' ID) 587 | ID '=' INT -> ^(TYPE 'int' ID INT) 588 ) 589 ';' 590 ; 591 ID : 'a'..'z'+ ; 592 INT : '0'..'9'+; 593 WS : (' '|'\n') {$channel=HIDDEN;} ; 594 595 END 596 result.should == '(TYPE int a) (TYPE int b 3)' 597 end 598 599 600 example "nested rewrite shuts off auto ast" do 601 result = parse( <<-'END', :a, 'a b c d; 42' ) 602 grammar NestedRewriteShutsOffAutoAST; 603 options {language=Ruby;output=AST;} 604 tokens {BLOCK;} 605 a : b b ; 606 b : ID ( ID (last=ID -> $last)+ ) ';' // get last ID 607 | INT // should still get auto AST construction 608 ; 609 ID : 'a'..'z'+ ; 610 INT : '0'..'9'+; 611 WS : (' '|'\n') {$channel=HIDDEN;} ; 612 613 END 614 result.should == 'd 42' 615 end 616 617 618 example "rewrite actions" do 619 result = parse( <<-'END', :a, '3' ) 620 grammar RewriteActions; 621 options {language=Ruby;output=AST;} 622 a : atom -> ^({ @adaptor.create( INT, "9" ) } atom) ; 623 atom : INT ; 624 ID : 'a'..'z'+ ; 625 INT : '0'..'9'+; 626 WS : (' '|'\n') {$channel=HIDDEN;} ; 627 628 END 629 result.should == '(9 3)' 630 end 631 632 633 example "rewrite actions2" do 634 result = parse( <<-'END', :a, '3' ) 635 grammar RewriteActions2; 636 options {language=Ruby;output=AST;} 637 a : atom -> { @adaptor.create( INT, "9" ) } atom ; 638 atom : INT ; 639 ID : 'a'..'z'+ ; 640 INT : '0'..'9'+; 641 WS : (' '|'\n') { $channel = HIDDEN } ; 642 643 END 644 result.should == '9 3' 645 end 646 647 648 example "ref to old value" do 649 result = parse( <<-'END', :a, '3+4+5' ) 650 grammar RefToOldValue; 651 options {language=Ruby;output=AST;} 652 tokens {BLOCK;} 653 a : (atom -> atom) (op='+' r=atom -> ^($op $a $r) )* ; 654 atom : INT ; 655 ID : 'a'..'z'+ ; 656 INT : '0'..'9'+; 657 WS : (' '|'\n') {$channel=HIDDEN;} ; 658 659 END 660 result.should == '(+ (+ 3 4) 5)' 661 end 662 663 664 example "copy semantics for rules" do 665 result = parse( <<-'END', :a, '3' ) 666 grammar CopySemanticsForRules; 667 options {language=Ruby;output=AST;} 668 tokens {BLOCK;} 669 a : atom -> ^(atom atom) ; // NOT CYCLE! (dup atom) 670 atom : INT ; 671 ID : 'a'..'z'+ ; 672 INT : '0'..'9'+; 673 WS : (' '|'\n') {$channel=HIDDEN;} ; 674 675 END 676 result.should == '(3 3)' 677 end 678 679 680 example "copy semantics for rules2" do 681 result = parse( <<-'END', :a, 'int a,b,c;' ) 682 grammar CopySemanticsForRules2; 683 options {language=Ruby;output=AST;} 684 a : type ID (',' ID)* ';' -> ^(type ID)+ ; 685 type : 'int' ; 686 ID : 'a'..'z'+ ; 687 WS : (' '|'\n') {$channel=HIDDEN;} ; 688 689 END 690 result.should == '(int a) (int b) (int c)' 691 end 692 693 694 example "copy semantics for rules3" do 695 result = parse( <<-'END', :a, 'public int a,b,c;' ) 696 grammar CopySemanticsForRules3; 697 options {language=Ruby;output=AST;} 698 a : modifier? type ID (',' ID)* ';' -> ^(type modifier? ID)+ ; 699 type : 'int' ; 700 modifier : 'public' ; 701 ID : 'a'..'z'+ ; 702 WS : (' '|'\n') {$channel=HIDDEN;} ; 703 704 END 705 result.should == '(int public a) (int public b) (int public c)' 706 end 707 708 709 example "copy semantics for rules3 double" do 710 result = parse( <<-'END', :a, 'public int a,b,c;' ) 711 grammar CopySemanticsForRules3Double; 712 options {language=Ruby;output=AST;} 713 a : modifier? type ID (',' ID)* ';' -> ^(type modifier? ID)+ ^(type modifier? ID)+ ; 714 type : 'int' ; 715 modifier : 'public' ; 716 ID : 'a'..'z'+ ; 717 WS : (' '|'\n') {$channel=HIDDEN;} ; 718 719 END 720 result.should == '(int public a) (int public b) (int public c) (int public a) (int public b) (int public c)' 721 end 722 723 724 example "copy semantics for rules4" do 725 result = parse( <<-'END', :a, 'public int a,b,c;' ) 726 grammar CopySemanticsForRules4; 727 options {language=Ruby;output=AST;} 728 tokens {MOD;} 729 a : modifier? type ID (',' ID)* ';' -> ^(type ^(MOD modifier)? ID)+ ; 730 type : 'int' ; 731 modifier : 'public' ; 732 ID : 'a'..'z'+ ; 733 WS : (' '|'\n') {$channel=HIDDEN;} ; 734 735 END 736 result.should == '(int (MOD public) a) (int (MOD public) b) (int (MOD public) c)' 737 end 738 739 740 example "copy semantics lists" do 741 result = parse( <<-'END', :a, 'a,b,c;' ) 742 grammar CopySemanticsLists; 743 options {language=Ruby;output=AST;} 744 tokens {MOD;} 745 a : ID (',' ID)* ';' -> ID+ ID+ ; 746 ID : 'a'..'z'+ ; 747 WS : (' '|'\n') {$channel=HIDDEN;} ; 748 749 END 750 result.should == 'a b c a b c' 751 end 752 753 754 example "copy rule label" do 755 result = parse( <<-'END', :a, 'a' ) 756 grammar CopyRuleLabel; 757 options {language=Ruby;output=AST;} 758 tokens {BLOCK;} 759 a : x=b -> $x $x; 760 b : ID ; 761 ID : 'a'..'z'+ ; 762 WS : (' '|'\n') {$channel=HIDDEN;} ; 763 764 END 765 result.should == 'a a' 766 end 767 768 769 example "copy rule label2" do 770 result = parse( <<-'END', :a, 'a' ) 771 grammar CopyRuleLabel2; 772 options {language=Ruby;output=AST;} 773 tokens {BLOCK;} 774 a : x=b -> ^($x $x); 775 b : ID ; 776 ID : 'a'..'z'+ ; 777 WS : (' '|'\n') {$channel=HIDDEN;} ; 778 779 END 780 result.should == '(a a)' 781 end 782 783 784 example "queueing of tokens" do 785 result = parse( <<-'END', :a, 'int a,b,c;' ) 786 grammar QueueingOfTokens; 787 options {language=Ruby;output=AST;} 788 a : 'int' ID (',' ID)* ';' -> ^('int' ID+) ; 789 op : '+'|'-' ; 790 ID : 'a'..'z'+ ; 791 INT : '0'..'9'+; 792 WS : (' '|'\n') {$channel=HIDDEN;} ; 793 794 END 795 result.should == '(int a b c)' 796 end 797 798 799 example "copy of tokens" do 800 result = parse( <<-'END', :a, 'int a;' ) 801 grammar CopyOfTokens; 802 options {language=Ruby;output=AST;} 803 a : 'int' ID ';' -> 'int' ID 'int' ID ; 804 op : '+'|'-' ; 805 ID : 'a'..'z'+ ; 806 INT : '0'..'9'+; 807 WS : (' '|'\n') {$channel=HIDDEN;} ; 808 809 END 810 result.should == 'int a int a' 811 end 812 813 814 example "token copy in loop" do 815 result = parse( <<-'END', :a, 'int a,b,c;' ) 816 grammar TokenCopyInLoop; 817 options {language=Ruby;output=AST;} 818 a : 'int' ID (',' ID)* ';' -> ^('int' ID)+ ; 819 op : '+'|'-' ; 820 ID : 'a'..'z'+ ; 821 INT : '0'..'9'+; 822 WS : (' '|'\n') {$channel=HIDDEN;} ; 823 824 END 825 result.should == '(int a) (int b) (int c)' 826 end 827 828 829 example "token copy in loop against two others" do 830 result = parse( <<-'END', :a, 'int a:1,b:2,c:3;' ) 831 grammar TokenCopyInLoopAgainstTwoOthers; 832 options {language=Ruby;output=AST;} 833 a : 'int' ID ':' INT (',' ID ':' INT)* ';' -> ^('int' ID INT)+ ; 834 op : '+'|'-' ; 835 ID : 'a'..'z'+ ; 836 INT : '0'..'9'+; 837 WS : (' '|'\n') {$channel=HIDDEN;} ; 838 839 END 840 result.should == '(int a 1) (int b 2) (int c 3)' 841 end 842 843 844 example "list refd one at a time" do 845 result = parse( <<-'END', :a, 'a b c' ) 846 grammar ListRefdOneAtATime; 847 options {language=Ruby;output=AST;} 848 a : ID+ -> ID ID ID ; // works if 3 input IDs 849 op : '+'|'-' ; 850 ID : 'a'..'z'+ ; 851 INT : '0'..'9'+; 852 WS : (' '|'\n') {$channel=HIDDEN;} ; 853 854 END 855 result.should == 'a b c' 856 end 857 858 859 example "split list with labels" do 860 result = parse( <<-'END', :a, 'a b c' ) 861 grammar SplitListWithLabels; 862 options {language=Ruby;output=AST;} 863 tokens {VAR;} 864 a : first=ID others+=ID* -> $first VAR $others+ ; 865 op : '+'|'-' ; 866 ID : 'a'..'z'+ ; 867 INT : '0'..'9'+; 868 WS : (' '|'\n') {$channel=HIDDEN;} ; 869 870 END 871 result.should == 'a VAR b c' 872 end 873 874 875 example "complicated melange" do 876 result = parse( <<-'END', :a, 'a a b b b c c c d' ) 877 grammar ComplicatedMelange; 878 options {language=Ruby;output=AST;} 879 tokens {BLOCK;} 880 a : A A b=B B b=B c+=C C c+=C D {s=$D.text} -> A+ B+ C+ D ; 881 type : 'int' | 'float' ; 882 A : 'a' ; 883 B : 'b' ; 884 C : 'c' ; 885 D : 'd' ; 886 WS : (' '|'\n') {$channel=HIDDEN;} ; 887 888 END 889 result.should == 'a a b b b c c c d' 890 end 891 892 893 example "rule label" do 894 result = parse( <<-'END', :a, 'a' ) 895 grammar RuleLabel; 896 options {language=Ruby;output=AST;} 897 tokens {BLOCK;} 898 a : x=b -> $x; 899 b : ID ; 900 ID : 'a'..'z'+ ; 901 WS : (' '|'\n') {$channel=HIDDEN;} ; 902 903 END 904 result.should == 'a' 905 end 906 907 908 example "ambiguous rule" do 909 result = parse( <<-'END', :a, 'abc 34' ) 910 grammar AmbiguousRule; 911 options {language=Ruby;output=AST;} 912 a : ID a -> a | INT ; 913 ID : 'a'..'z'+ ; 914 INT: '0'..'9'+ ; 915 WS : (' '|'\n') {$channel=HIDDEN;} ; 916 917 END 918 result.should == '34' 919 end 920 921 922 example "rule list label" do 923 result = parse( <<-'END', :a, 'a b' ) 924 grammar RuleListLabel; 925 options {language=Ruby;output=AST;} 926 tokens {BLOCK;} 927 a : x+=b x+=b -> $x+; 928 b : ID ; 929 ID : 'a'..'z'+ ; 930 WS : (' '|'\n') {$channel=HIDDEN;} ; 931 932 END 933 result.should == 'a b' 934 end 935 936 937 example "rule list label2" do 938 result = parse( <<-'END', :a, 'a b' ) 939 grammar RuleListLabel2; 940 options {language=Ruby;output=AST;} 941 tokens {BLOCK;} 942 a : x+=b x+=b -> $x $x*; 943 b : ID ; 944 ID : 'a'..'z'+ ; 945 WS : (' '|'\n') {$channel=HIDDEN;} ; 946 947 END 948 result.should == 'a b' 949 end 950 951 952 example "optional" do 953 result = parse( <<-'END', :a, 'a' ) 954 grammar Optional; 955 options {language=Ruby;output=AST;} 956 tokens {BLOCK;} 957 a : x=b (y=b)? -> $x $y?; 958 b : ID ; 959 ID : 'a'..'z'+ ; 960 WS : (' '|'\n') {$channel=HIDDEN;} ; 961 962 END 963 result.should == 'a' 964 end 965 966 967 example "optional2" do 968 result = parse( <<-'END', :a, 'a b' ) 969 grammar Optional2; 970 options {language=Ruby;output=AST;} 971 tokens {BLOCK;} 972 a : x=ID (y=b)? -> $x $y?; 973 b : ID ; 974 ID : 'a'..'z'+ ; 975 WS : (' '|'\n') {$channel=HIDDEN;} ; 976 977 END 978 result.should == 'a b' 979 end 980 981 982 example "optional3" do 983 result = parse( <<-'END', :a, 'a b' ) 984 grammar Optional3; 985 options {language=Ruby;output=AST;} 986 tokens {BLOCK;} 987 a : x=ID (y=b)? -> ($x $y)?; 988 b : ID ; 989 ID : 'a'..'z'+ ; 990 WS : (' '|'\n') {$channel=HIDDEN;} ; 991 992 END 993 result.should == 'a b' 994 end 995 996 997 example "optional4" do 998 result = parse( <<-'END', :a, 'a b' ) 999 grammar Optional4; 1000 options {language=Ruby;output=AST;} 1001 tokens {BLOCK;} 1002 a : x+=ID (y=b)? -> ($x $y)?; 1003 b : ID ; 1004 ID : 'a'..'z'+ ; 1005 WS : (' '|'\n') {$channel=HIDDEN;} ; 1006 END 1007 result.should == 'a b' 1008 end 1009 1010 1011 example "optional5" do 1012 result = parse( <<-'END', :a, 'a' ) 1013 grammar Optional5; 1014 options {language=Ruby;output=AST;} 1015 tokens {BLOCK;} 1016 a : ID -> ID? ; // match an ID to optional ID 1017 b : ID ; 1018 ID : 'a'..'z'+ ; 1019 WS : (' '|'\n') {$channel=HIDDEN;} ; 1020 1021 END 1022 result.should == 'a' 1023 end 1024 1025 1026 example "arbitrary expr type" do 1027 result = parse( <<-'END', :a, 'a b' ) 1028 grammar ArbitraryExprType; 1029 options {language=Ruby;output=AST;} 1030 tokens {BLOCK;} 1031 a : x+=b x+=b -> {ANTLR3::CommonTree.new(nil)}; 1032 b : ID ; 1033 ID : 'a'..'z'+ ; 1034 WS : (' '|'\n') {$channel=HIDDEN;} ; 1035 1036 END 1037 result.should == '' 1038 end 1039 1040 1041 example "set" do 1042 result = parse( <<-'END', :a, '2 a 34 de' ) 1043 grammar SetT; 1044 options {language=Ruby;output=AST;} 1045 a: (INT|ID)+ -> INT+ ID+ ; 1046 INT: '0'..'9'+; 1047 ID : 'a'..'z'+; 1048 WS : (' '|'\n') {$channel=HIDDEN;} ; 1049 1050 END 1051 result.should == '2 34 a de' 1052 end 1053 1054 1055 example "set2" do 1056 result = parse( <<-'END', :a, '2' ) 1057 grammar Set2; 1058 options {language=Ruby;output=AST;} 1059 a: (INT|ID) -> INT? ID? ; 1060 INT: '0'..'9'+; 1061 ID : 'a'..'z'+; 1062 WS : (' '|'\n') {$channel=HIDDEN;} ; 1063 1064 END 1065 result.should == '2' 1066 end 1067 1068 1069 example "set with label" do 1070 warn( 'test SetWithLabel officially broken' ) 1071 #result = parse(<<-'END', :a, '2') 1072 # grammar SetWithLabel; 1073 # options {language=Ruby;output=AST;} 1074 # a : x=(INT|ID) -> $x ; 1075 # INT: '0'..'9'+; 1076 # ID : 'a'..'z'+; 1077 # WS : (' '|'\n') {$channel=HIDDEN;} ; 1078 # 1079 #END 1080 #result.should == '2' 1081 end 1082 1083 1084 example "rewrite action" do 1085 result = parse( <<-'END', :r, '25' ) 1086 grammar RewriteAction; 1087 options {language=Ruby;output=AST;} 1088 tokens { FLOAT; } 1089 r 1090 : INT -> { ANTLR3::CommonTree.new( create_token( FLOAT, nil, "#{$INT.text}.0" ) ) } 1091 ; 1092 INT : '0'..'9'+; 1093 WS: (' ' | '\n' | '\t')+ {$channel = HIDDEN;}; 1094 1095 END 1096 result.should == '25.0' 1097 end 1098 1099 1100 example "optional subrule without real elements" do 1101 result = parse( <<-'END', :modulo, 'modulo abc (x y #)' ) 1102 grammar OptionalSubruleWithoutRealElements; 1103 options {language=Ruby;output=AST;} 1104 tokens {PARMS;} 1105 1106 modulo 1107 : 'modulo' ID ('(' parms+ ')')? -> ^('modulo' ID ^(PARMS parms+)?) 1108 ; 1109 parms : '#'|ID; 1110 ID : ('a'..'z' | 'A'..'Z')+; 1111 WS : (' '|'\n') {$channel=HIDDEN;} ; 1112 1113 END 1114 result.should == '(modulo abc (PARMS x y #))' 1115 end 1116 1117 1118 example "wildcard" do 1119 result = parse( <<-'END', :a, 'abc 34' ) 1120 grammar Wildcard; 1121 options {language=Ruby;output=AST;} 1122 a : ID c=. -> $c; 1123 ID : 'a'..'z'+ ; 1124 INT : '0'..'9'+; 1125 WS : (' '|'\n') {$channel=HIDDEN;} ; 1126 1127 END 1128 result.should == '34' 1129 end 1130 1131 1132 example "extra token in simple decl" do 1133 result, errors = parse( <<-'END', :decl, 'int 34 x=1;', true ) 1134 grammar ExtraTokenInSimpleDecl; 1135 options {language=Ruby;output=AST;} 1136 tokens {EXPR;} 1137 decl : type ID '=' INT ';' -> ^(EXPR type ID INT) ; 1138 type : 'int' | 'float' ; 1139 ID : 'a'..'z'+ ; 1140 INT : '0'..'9'+; 1141 WS : (' '|'\n') {$channel=HIDDEN;} ; 1142 1143 END 1144 errors.should == [ 'line 1:4 extraneous input "34" expecting ID' ] 1145 result.should == '(EXPR int x 1)' 1146 end 1147 1148 1149 example "missing id in simple decl" do 1150 result, errors = parse( <<-'END', :decl, 'int =1;', true ) 1151 grammar MissingIDInSimpleDecl; 1152 options {language=Ruby;output=AST;} 1153 tokens {EXPR;} 1154 decl : type ID '=' INT ';' -> ^(EXPR type ID INT) ; 1155 type : 'int' | 'float' ; 1156 ID : 'a'..'z'+ ; 1157 INT : '0'..'9'+; 1158 WS : (' '|'\n') {$channel=HIDDEN;} ; 1159 1160 END 1161 errors.should == [ 'line 1:4 missing ID at "="' ] 1162 result.should == '(EXPR int <missing ID> 1)' 1163 end 1164 1165 1166 example "missing set in simple decl" do 1167 result, errors = parse( <<-'END', :decl, 'x=1;', true ) 1168 grammar MissingSetInSimpleDecl; 1169 options {language=Ruby;output=AST;} 1170 tokens {EXPR;} 1171 decl : type ID '=' INT ';' -> ^(EXPR type ID INT) ; 1172 type : 'int' | 'float' ; 1173 ID : 'a'..'z'+ ; 1174 INT : '0'..'9'+; 1175 WS : (' '|'\n') {$channel=HIDDEN;} ; 1176 1177 END 1178 errors.should == [ 'line 1:0 mismatched input "x" expecting set nil' ] 1179 result.should == '(EXPR <error: x> x 1)' 1180 end 1181 1182 1183 example "missing token gives error node" do 1184 result, errors = parse( <<-'END', :a, 'abc', true ) 1185 grammar MissingTokenGivesErrorNode; 1186 options {language=Ruby;output=AST;} 1187 a : ID INT -> ID INT ; 1188 ID : 'a'..'z'+ ; 1189 INT : '0'..'9'+; 1190 WS : (' '|'\n') {$channel=HIDDEN;} ; 1191 1192 END 1193 errors.should == [ "line 0:-1 missing INT at \"<EOF>\"" ] 1194 result.should == 'abc <missing INT>' 1195 #end 1196 end 1197 1198 1199 example "extra token gives error node" do 1200 result, errors = parse( <<-'END', :a, 'abc ick 34', true ) 1201 grammar ExtraTokenGivesErrorNode; 1202 options {language=Ruby;output=AST;} 1203 a : b c -> b c; 1204 b : ID -> ID ; 1205 c : INT -> INT ; 1206 ID : 'a'..'z'+ ; 1207 INT : '0'..'9'+; 1208 WS : (' '|'\n') {$channel=HIDDEN;} ; 1209 1210 END 1211 errors.should == [ 'line 1:4 extraneous input "ick" expecting INT' ] 1212 result.should == 'abc 34' 1213 end 1214 1215 1216 example "missing first token gives error node" do 1217 result, errors = parse( <<-'END', :a, '34', true ) 1218 grammar MissingFirstTokenGivesErrorNode; 1219 options {language=Ruby;output=AST;} 1220 a : ID INT -> ID INT ; 1221 ID : 'a'..'z'+ ; 1222 INT : '0'..'9'+; 1223 WS : (' '|'\n') {$channel=HIDDEN;} ; 1224 1225 END 1226 errors.should == [ 'line 1:0 missing ID at "34"' ] 1227 result.should == '<missing ID> 34' 1228 end 1229 1230 1231 example "missing first token gives error node2" do 1232 result, errors = parse( <<-'END', :a, '34', true ) 1233 grammar MissingFirstTokenGivesErrorNode2; 1234 options {language=Ruby;output=AST;} 1235 a : b c -> b c; 1236 b : ID -> ID ; 1237 c : INT -> INT ; 1238 ID : 'a'..'z'+ ; 1239 INT : '0'..'9'+; 1240 WS : (' '|'\n') {$channel=HIDDEN;} ; 1241 1242 END 1243 errors.should == [ 'line 1:0 missing ID at "34"' ] 1244 result.should == '<missing ID> 34' 1245 end 1246 1247 1248 example "no viable alt gives error node" do 1249 result, errors = parse( <<-'END', :a, '*', true ) 1250 grammar NoViableAltGivesErrorNode; 1251 options {language=Ruby;output=AST;} 1252 a : b -> b | c -> c; 1253 b : ID -> ID ; 1254 c : INT -> INT ; 1255 ID : 'a'..'z'+ ; 1256 S : '*' ; 1257 INT : '0'..'9'+; 1258 WS : (' '|'\n') {$channel=HIDDEN;} ; 1259 1260 END 1261 errors.should == [ 'line 1:0 no viable alternative at input "*"' ] 1262 result.should == '<unexpected: 0 S["*"] @ line 1 col 0 (0..0), resync = *>' 1263 end 1264 1265 1266 example "cardinality" do 1267 lambda do 1268 parse( <<-'END', :a, "a b 3 4 5" ) 1269 grammar Cardinality; 1270 options {language=Ruby;output=AST;} 1271 tokens {BLOCK;} 1272 a : ID ID INT INT INT -> (ID INT)+; 1273 ID : 'a'..'z'+ ; 1274 INT : '0'..'9'+; 1275 WS : (' '|'\n') {$channel=HIDDEN;} ; 1276 END 1277 end.should raise_error( ANTLR3::Error::RewriteCardinalityError ) 1278 end 1279 1280 example "cardinality2" do 1281 lambda do 1282 parse( <<-'END', :a, "a b" ) 1283 grammar Cardinality2; 1284 options {language=Ruby;output=AST;} 1285 tokens {BLOCK;} 1286 a : ID+ -> ID ID ID ; // only 2 input IDs 1287 op : '+'|'-' ; 1288 ID : 'a'..'z'+ ; 1289 INT : '0'..'9'+; 1290 WS : (' '|'\n') {$channel=HIDDEN;} ; 1291 END 1292 end.should raise_error( ANTLR3::Error::RewriteCardinalityError ) 1293 end 1294 1295 example "cardinality3" do 1296 lambda do 1297 parse( <<-'END', :a, "3" ) 1298 grammar Cardinality3; 1299 options {language=Ruby;output=AST;} 1300 tokens {BLOCK;} 1301 a : ID? INT -> ID INT ; 1302 op : '+'|'-' ; 1303 ID : 'a'..'z'+ ; 1304 INT : '0'..'9'+; 1305 WS : (' '|'\n') {$channel=HIDDEN;} ; 1306 END 1307 end.should raise_error( ANTLR3::Error::RewriteEmptyStream ) 1308 end 1309 1310 example "loop cardinality" do 1311 lambda do 1312 parse( <<-'END', :a, "3" ) 1313 grammar LoopCardinality; 1314 options {language=Ruby;output=AST;} 1315 a : ID? INT -> ID+ INT ; 1316 op : '+'|'-' ; 1317 ID : 'a'..'z'+ ; 1318 INT : '0'..'9'+; 1319 WS : (' '|'\n') {$channel=HIDDEN;} ; 1320 END 1321 end.should raise_error( ANTLR3::Error::RewriteEarlyExit ) 1322 end 1323 1324 1325 1326 end 1327