1 /* 2 * [The "BSD license"] 3 * Copyright (c) 2010 Terence Parr 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 package org.antlr.test; 29 30 import org.antlr.Tool; 31 import org.antlr.analysis.Label; 32 import org.antlr.codegen.CodeGenerator; 33 import org.stringtemplate.v4.ST; 34 import org.antlr.tool.*; 35 import org.junit.Test; 36 37 import java.util.*; 38 39 public class TestSymbolDefinitions extends BaseTest { 40 41 /** Public default constructor used by TestRig */ TestSymbolDefinitions()42 public TestSymbolDefinitions() { 43 } 44 testParserSimpleTokens()45 @Test public void testParserSimpleTokens() throws Exception { 46 Grammar g = new Grammar( 47 "parser grammar t;\n"+ 48 "a : A | B;\n" + 49 "b : C ;"); 50 String rules = "a, b"; 51 String tokenNames = "A, B, C"; 52 checkSymbols(g, rules, tokenNames); 53 } 54 testParserTokensSection()55 @Test public void testParserTokensSection() throws Exception { 56 Grammar g = new Grammar( 57 "parser grammar t;\n" + 58 "tokens {\n" + 59 " C;\n" + 60 " D;" + 61 "}\n"+ 62 "a : A | B;\n" + 63 "b : C ;"); 64 String rules = "a, b"; 65 String tokenNames = "A, B, C, D"; 66 checkSymbols(g, rules, tokenNames); 67 } 68 testLexerTokensSection()69 @Test public void testLexerTokensSection() throws Exception { 70 Grammar g = new Grammar( 71 "lexer grammar t;\n" + 72 "tokens {\n" + 73 " C;\n" + 74 " D;" + 75 "}\n"+ 76 "A : 'a';\n" + 77 "C : 'c' ;"); 78 String rules = "A, C, Tokens"; 79 String tokenNames = "A, C, D"; 80 checkSymbols(g, rules, tokenNames); 81 } 82 testTokensSectionWithAssignmentSection()83 @Test public void testTokensSectionWithAssignmentSection() throws Exception { 84 Grammar g = new Grammar( 85 "grammar t;\n" + 86 "tokens {\n" + 87 " C='c';\n" + 88 " D;" + 89 "}\n"+ 90 "a : A | B;\n" + 91 "b : C ;"); 92 String rules = "a, b"; 93 String tokenNames = "A, B, C, D, 'c'"; 94 checkSymbols(g, rules, tokenNames); 95 } 96 testCombinedGrammarLiterals()97 @Test public void testCombinedGrammarLiterals() throws Exception { 98 Grammar g = new Grammar( 99 "grammar t;\n"+ 100 "a : 'begin' b 'end';\n" + 101 "b : C ';' ;\n" + 102 "ID : 'a' ;\n" + 103 "FOO : 'foo' ;\n" + // "foo" is not a token name 104 "C : 'c' ;\n"); // nor is 'c' 105 String rules = "a, b"; 106 String tokenNames = "C, FOO, ID, 'begin', 'end', ';'"; 107 checkSymbols(g, rules, tokenNames); 108 } 109 testLiteralInParserAndLexer()110 @Test public void testLiteralInParserAndLexer() throws Exception { 111 // 'x' is token and char in lexer rule 112 Grammar g = new Grammar( 113 "grammar t;\n" + 114 "a : 'x' E ; \n" + 115 "E: 'x' '0' ;\n"); // nor is 'c' 116 String literals = "['x']"; 117 String foundLiterals = g.getStringLiterals().toString(); 118 assertEquals(literals, foundLiterals); 119 120 String implicitLexer = 121 "lexer grammar t;" + newline + 122 "T__5 : 'x' ;" + newline + 123 "" + newline + 124 "// $ANTLR src \"<string>\" 3" + newline + 125 "E: 'x' '0' ;"; 126 assertEquals(implicitLexer, g.getLexerGrammar()); 127 } 128 testCombinedGrammarWithRefToLiteralButNoTokenIDRef()129 @Test public void testCombinedGrammarWithRefToLiteralButNoTokenIDRef() throws Exception { 130 Grammar g = new Grammar( 131 "grammar t;\n"+ 132 "a : 'a' ;\n" + 133 "A : 'a' ;\n"); 134 String rules = "a"; 135 String tokenNames = "A, 'a'"; 136 checkSymbols(g, rules, tokenNames); 137 } 138 testSetDoesNotMissTokenAliases()139 @Test public void testSetDoesNotMissTokenAliases() throws Exception { 140 Grammar g = new Grammar( 141 "grammar t;\n"+ 142 "a : 'a'|'b' ;\n" + 143 "A : 'a' ;\n" + 144 "B : 'b' ;\n"); 145 String rules = "a"; 146 String tokenNames = "A, 'a', B, 'b'"; 147 checkSymbols(g, rules, tokenNames); 148 } 149 testSimplePlusEqualLabel()150 @Test public void testSimplePlusEqualLabel() throws Exception { 151 Grammar g = new Grammar( 152 "parser grammar t;\n"+ 153 "a : ids+=ID ( COMMA ids+=ID )* ;\n"); 154 String rule = "a"; 155 String tokenLabels = "ids"; 156 String ruleLabels = null; 157 checkPlusEqualsLabels(g, rule, tokenLabels, ruleLabels); 158 } 159 testMixedPlusEqualLabel()160 @Test public void testMixedPlusEqualLabel() throws Exception { 161 Grammar g = new Grammar( 162 "grammar t;\n"+ 163 "options {output=AST;}\n" + 164 "a : id+=ID ( ',' e+=expr )* ;\n" + 165 "expr : 'e';\n" + 166 "ID : 'a';\n"); 167 String rule = "a"; 168 String tokenLabels = "id"; 169 String ruleLabels = "e"; 170 checkPlusEqualsLabels(g, rule, tokenLabels, ruleLabels); 171 } 172 173 // T E S T L I T E R A L E S C A P E S 174 testParserCharLiteralWithEscape()175 @Test public void testParserCharLiteralWithEscape() throws Exception { 176 Grammar g = new Grammar( 177 "grammar t;\n"+ 178 "a : '\\n';\n"); 179 Set literals = g.getStringLiterals(); 180 // must store literals how they appear in the antlr grammar 181 assertEquals("'\\n'", literals.toArray()[0]); 182 } 183 testTokenInTokensSectionAndTokenRuleDef()184 @Test public void testTokenInTokensSectionAndTokenRuleDef() throws Exception { 185 // this must return A not I to the parser; calling a nonfragment rule 186 // from a nonfragment rule does not set the overall token. 187 String grammar = 188 "grammar P;\n" + 189 "tokens { B='}'; }\n"+ 190 "a : A B {System.out.println(input);} ;\n"+ 191 "A : 'a' ;\n" + 192 "B : '}' ;\n"+ 193 "WS : (' '|'\\n') {$channel=HIDDEN;} ;"; 194 String found = execParser("P.g", grammar, "PParser", "PLexer", 195 "a", "a}", false); 196 assertEquals("a}\n", found); 197 } 198 testTokenInTokensSectionAndTokenRuleDef2()199 @Test public void testTokenInTokensSectionAndTokenRuleDef2() throws Exception { 200 // this must return A not I to the parser; calling a nonfragment rule 201 // from a nonfragment rule does not set the overall token. 202 String grammar = 203 "grammar P;\n" + 204 "tokens { B='}'; }\n"+ 205 "a : A '}' {System.out.println(input);} ;\n"+ 206 "A : 'a' ;\n" + 207 "B : '}' {/* */} ;\n"+ 208 "WS : (' '|'\\n') {$channel=HIDDEN;} ;"; 209 String found = execParser("P.g", grammar, "PParser", "PLexer", 210 "a", "a}", false); 211 assertEquals("a}\n", found); 212 } 213 214 testRefToRuleWithNoReturnValue()215 @Test public void testRefToRuleWithNoReturnValue() throws Exception { 216 ErrorQueue equeue = new ErrorQueue(); 217 ErrorManager.setErrorListener(equeue); 218 219 String grammarStr = 220 "grammar P;\n" + 221 "a : x=b ;\n" + 222 "b : B ;\n" + 223 "B : 'b' ;\n"; 224 Grammar g = new Grammar(grammarStr); 225 226 Tool antlr = newTool(); 227 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 228 g.setCodeGenerator(generator); 229 ST recogST = generator.genRecognizer(); 230 String code = recogST.render(); 231 assertTrue("not expecting label", code.indexOf("x=b();")<0); 232 233 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 234 } 235 236 // T E S T E R R O R S 237 testParserStringLiterals()238 @Test public void testParserStringLiterals() throws Exception { 239 ErrorQueue equeue = new ErrorQueue(); 240 ErrorManager.setErrorListener(equeue); 241 Grammar g = new Grammar( 242 "parser grammar t;\n"+ 243 "a : 'begin' b ;\n" + 244 "b : C ;"); 245 Object expectedArg = "'begin'"; 246 int expectedMsgID = ErrorManager.MSG_LITERAL_NOT_ASSOCIATED_WITH_LEXER_RULE; 247 GrammarSemanticsMessage expectedMessage = 248 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 249 checkGrammarSemanticsError(equeue, expectedMessage); 250 } 251 testParserCharLiterals()252 @Test public void testParserCharLiterals() throws Exception { 253 ErrorQueue equeue = new ErrorQueue(); 254 ErrorManager.setErrorListener(equeue); 255 Grammar g = new Grammar( 256 "parser grammar t;\n"+ 257 "a : '(' b ;\n" + 258 "b : C ;"); 259 Object expectedArg = "'('"; 260 int expectedMsgID = ErrorManager.MSG_LITERAL_NOT_ASSOCIATED_WITH_LEXER_RULE; 261 GrammarSemanticsMessage expectedMessage = 262 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 263 checkGrammarSemanticsError(equeue, expectedMessage); 264 } 265 testEmptyNotChar()266 @Test public void testEmptyNotChar() throws Exception { 267 ErrorQueue equeue = new ErrorQueue(); 268 ErrorManager.setErrorListener(equeue); 269 Grammar g = new Grammar( 270 "grammar foo;\n" + 271 "a : (~'x')+ ;\n"); 272 g.buildNFA(); 273 Object expectedArg = "'x'"; 274 int expectedMsgID = ErrorManager.MSG_EMPTY_COMPLEMENT; 275 GrammarSemanticsMessage expectedMessage = 276 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 277 checkGrammarSemanticsError(equeue, expectedMessage); 278 } 279 testEmptyNotToken()280 @Test public void testEmptyNotToken() throws Exception { 281 ErrorQueue equeue = new ErrorQueue(); 282 ErrorManager.setErrorListener(equeue); 283 Grammar g = new Grammar( 284 "grammar foo;\n" + 285 "a : (~A)+ ;\n"); 286 g.buildNFA(); 287 Object expectedArg = "A"; 288 int expectedMsgID = ErrorManager.MSG_EMPTY_COMPLEMENT; 289 GrammarSemanticsMessage expectedMessage = 290 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 291 checkGrammarSemanticsError(equeue, expectedMessage); 292 } 293 testEmptyNotSet()294 @Test public void testEmptyNotSet() throws Exception { 295 ErrorQueue equeue = new ErrorQueue(); 296 ErrorManager.setErrorListener(equeue); 297 Grammar g = new Grammar( 298 "grammar foo;\n" + 299 "a : (~(A|B))+ ;\n"); 300 g.buildNFA(); 301 Object expectedArg = null; 302 int expectedMsgID = ErrorManager.MSG_EMPTY_COMPLEMENT; 303 GrammarSemanticsMessage expectedMessage = 304 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 305 checkGrammarSemanticsError(equeue, expectedMessage); 306 } 307 testStringLiteralInParserTokensSection()308 @Test public void testStringLiteralInParserTokensSection() throws Exception { 309 ErrorQueue equeue = new ErrorQueue(); 310 ErrorManager.setErrorListener(equeue); // unique listener per thread 311 Grammar g = new Grammar( 312 "parser grammar t;\n" + 313 "tokens {\n" + 314 " B='begin';\n" + 315 "}\n"+ 316 "a : A B;\n" + 317 "b : C ;"); 318 Object expectedArg = "'begin'"; 319 int expectedMsgID = ErrorManager.MSG_LITERAL_NOT_ASSOCIATED_WITH_LEXER_RULE; 320 GrammarSemanticsMessage expectedMessage = 321 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 322 checkGrammarSemanticsError(equeue, expectedMessage); 323 } 324 testCharLiteralInParserTokensSection()325 @Test public void testCharLiteralInParserTokensSection() throws Exception { 326 ErrorQueue equeue = new ErrorQueue(); 327 ErrorManager.setErrorListener(equeue); // unique listener per thread 328 Grammar g = new Grammar( 329 "parser grammar t;\n" + 330 "tokens {\n" + 331 " B='(';\n" + 332 "}\n"+ 333 "a : A B;\n" + 334 "b : C ;"); 335 Object expectedArg = "'('"; 336 int expectedMsgID = ErrorManager.MSG_LITERAL_NOT_ASSOCIATED_WITH_LEXER_RULE; 337 GrammarSemanticsMessage expectedMessage = 338 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 339 checkGrammarSemanticsError(equeue, expectedMessage); 340 } 341 testCharLiteralInLexerTokensSection()342 @Test public void testCharLiteralInLexerTokensSection() throws Exception { 343 ErrorQueue equeue = new ErrorQueue(); 344 ErrorManager.setErrorListener(equeue); // unique listener per thread 345 Grammar g = new Grammar( 346 "lexer grammar t;\n" + 347 "tokens {\n" + 348 " B='(';\n" + 349 "}\n"+ 350 "ID : 'a';\n"); 351 Object expectedArg = "'('"; 352 int expectedMsgID = ErrorManager.MSG_CANNOT_ALIAS_TOKENS_IN_LEXER; 353 GrammarSemanticsMessage expectedMessage = 354 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 355 checkGrammarSemanticsError(equeue, expectedMessage); 356 } 357 testRuleRedefinition()358 @Test public void testRuleRedefinition() throws Exception { 359 ErrorQueue equeue = new ErrorQueue(); 360 ErrorManager.setErrorListener(equeue); // unique listener per thread 361 Grammar g = new Grammar( 362 "parser grammar t;\n"+ 363 "a : A | B;\n" + 364 "a : C ;"); 365 366 Object expectedArg = "a"; 367 int expectedMsgID = ErrorManager.MSG_RULE_REDEFINITION; 368 GrammarSemanticsMessage expectedMessage = 369 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 370 checkGrammarSemanticsError(equeue, expectedMessage); 371 } 372 testLexerRuleRedefinition()373 @Test public void testLexerRuleRedefinition() throws Exception { 374 ErrorQueue equeue = new ErrorQueue(); 375 ErrorManager.setErrorListener(equeue); // unique listener per thread 376 Grammar g = new Grammar( 377 "lexer grammar t;\n"+ 378 "ID : 'a' ;\n" + 379 "ID : 'd' ;"); 380 381 Object expectedArg = "ID"; 382 int expectedMsgID = ErrorManager.MSG_RULE_REDEFINITION; 383 GrammarSemanticsMessage expectedMessage = 384 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 385 checkGrammarSemanticsError(equeue, expectedMessage); 386 } 387 testCombinedRuleRedefinition()388 @Test public void testCombinedRuleRedefinition() throws Exception { 389 ErrorQueue equeue = new ErrorQueue(); 390 ErrorManager.setErrorListener(equeue); // unique listener per thread 391 Grammar g = new Grammar( 392 "grammar t;\n"+ 393 "x : ID ;\n" + 394 "ID : 'a' ;\n" + 395 "x : ID ID ;"); 396 397 Object expectedArg = "x"; 398 int expectedMsgID = ErrorManager.MSG_RULE_REDEFINITION; 399 GrammarSemanticsMessage expectedMessage = 400 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 401 checkGrammarSemanticsError(equeue, expectedMessage); 402 } 403 testUndefinedToken()404 @Test public void testUndefinedToken() throws Exception { 405 ErrorQueue equeue = new ErrorQueue(); 406 ErrorManager.setErrorListener(equeue); // unique listener per thread 407 Grammar g = new Grammar( 408 "grammar t;\n"+ 409 "x : ID ;"); 410 411 Object expectedArg = "ID"; 412 int expectedMsgID = ErrorManager.MSG_NO_TOKEN_DEFINITION; 413 GrammarSemanticsMessage expectedMessage = 414 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 415 checkGrammarSemanticsWarning(equeue, expectedMessage); 416 } 417 testUndefinedTokenOkInParser()418 @Test public void testUndefinedTokenOkInParser() throws Exception { 419 ErrorQueue equeue = new ErrorQueue(); 420 ErrorManager.setErrorListener(equeue); // unique listener per thread 421 Grammar g = new Grammar( 422 "parser grammar t;\n"+ 423 "x : ID ;"); 424 assertEquals("should not be an error", 0, equeue.errors.size()); 425 } 426 testUndefinedRule()427 @Test public void testUndefinedRule() throws Exception { 428 ErrorQueue equeue = new ErrorQueue(); 429 ErrorManager.setErrorListener(equeue); // unique listener per thread 430 Grammar g = new Grammar( 431 "grammar t;\n"+ 432 "x : r ;"); 433 434 Object expectedArg = "r"; 435 int expectedMsgID = ErrorManager.MSG_UNDEFINED_RULE_REF; 436 GrammarSemanticsMessage expectedMessage = 437 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 438 checkGrammarSemanticsError(equeue, expectedMessage); 439 } 440 testLexerRuleInParser()441 @Test public void testLexerRuleInParser() throws Exception { 442 ErrorQueue equeue = new ErrorQueue(); 443 ErrorManager.setErrorListener(equeue); // unique listener per thread 444 Grammar g = new Grammar( 445 "parser grammar t;\n"+ 446 "X : ;"); 447 448 Object expectedArg = "X"; 449 int expectedMsgID = ErrorManager.MSG_LEXER_RULES_NOT_ALLOWED; 450 GrammarSemanticsMessage expectedMessage = 451 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 452 checkGrammarSemanticsError(equeue, expectedMessage); 453 } 454 testParserRuleInLexer()455 @Test public void testParserRuleInLexer() throws Exception { 456 ErrorQueue equeue = new ErrorQueue(); 457 ErrorManager.setErrorListener(equeue); // unique listener per thread 458 Grammar g = new Grammar( 459 "lexer grammar t;\n"+ 460 "a : ;"); 461 462 Object expectedArg = "a"; 463 int expectedMsgID = ErrorManager.MSG_PARSER_RULES_NOT_ALLOWED; 464 GrammarSemanticsMessage expectedMessage = 465 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 466 checkGrammarSemanticsError(equeue, expectedMessage); 467 } 468 testRuleScopeConflict()469 @Test public void testRuleScopeConflict() throws Exception { 470 ErrorQueue equeue = new ErrorQueue(); 471 ErrorManager.setErrorListener(equeue); // unique listener per thread 472 Grammar g = new Grammar( 473 "grammar t;\n"+ 474 "scope a {\n" + 475 " int n;\n" + 476 "}\n" + 477 "a : \n" + 478 " ;\n"); 479 480 Object expectedArg = "a"; 481 int expectedMsgID = ErrorManager.MSG_SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE; 482 GrammarSemanticsMessage expectedMessage = 483 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 484 checkGrammarSemanticsError(equeue, expectedMessage); 485 } 486 testTokenRuleScopeConflict()487 @Test public void testTokenRuleScopeConflict() throws Exception { 488 ErrorQueue equeue = new ErrorQueue(); 489 ErrorManager.setErrorListener(equeue); // unique listener per thread 490 Grammar g = new Grammar( 491 "grammar t;\n"+ 492 "scope ID {\n" + 493 " int n;\n" + 494 "}\n" + 495 "ID : 'a'\n" + 496 " ;\n"); 497 498 Object expectedArg = "ID"; 499 int expectedMsgID = ErrorManager.MSG_SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE; 500 GrammarSemanticsMessage expectedMessage = 501 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 502 checkGrammarSemanticsError(equeue, expectedMessage); 503 } 504 testTokenScopeConflict()505 @Test public void testTokenScopeConflict() throws Exception { 506 ErrorQueue equeue = new ErrorQueue(); 507 ErrorManager.setErrorListener(equeue); // unique listener per thread 508 Grammar g = new Grammar( 509 "grammar t;\n"+ 510 "tokens { ID; }\n"+ 511 "scope ID {\n" + 512 " int n;\n" + 513 "}\n" + 514 "a : \n" + 515 " ;\n"); 516 517 Object expectedArg = "ID"; 518 int expectedMsgID = ErrorManager.MSG_SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE; 519 GrammarSemanticsMessage expectedMessage = 520 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 521 checkGrammarSemanticsError(equeue, expectedMessage); 522 } 523 testTokenRuleScopeConflictInLexerGrammar()524 @Test public void testTokenRuleScopeConflictInLexerGrammar() throws Exception { 525 ErrorQueue equeue = new ErrorQueue(); 526 ErrorManager.setErrorListener(equeue); // unique listener per thread 527 Grammar g = new Grammar( 528 "lexer grammar t;\n"+ 529 "scope ID {\n" + 530 " int n;\n" + 531 "}\n" + 532 "ID : 'a'\n" + 533 " ;\n"); 534 535 Object expectedArg = "ID"; 536 int expectedMsgID = ErrorManager.MSG_SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE; 537 GrammarSemanticsMessage expectedMessage = 538 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 539 checkGrammarSemanticsError(equeue, expectedMessage); 540 } 541 testTokenLabelScopeConflict()542 @Test public void testTokenLabelScopeConflict() throws Exception { 543 ErrorQueue equeue = new ErrorQueue(); 544 ErrorManager.setErrorListener(equeue); // unique listener per thread 545 Grammar g = new Grammar( 546 "parser grammar t;\n"+ 547 "scope s {\n" + 548 " int n;\n" + 549 "}\n" + 550 "a : s=ID \n" + 551 " ;\n"); 552 553 Object expectedArg = "s"; 554 int expectedMsgID = ErrorManager.MSG_SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE; 555 GrammarSemanticsMessage expectedMessage = 556 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 557 checkGrammarSemanticsError(equeue, expectedMessage); 558 } 559 testRuleLabelScopeConflict()560 @Test public void testRuleLabelScopeConflict() throws Exception { 561 ErrorQueue equeue = new ErrorQueue(); 562 ErrorManager.setErrorListener(equeue); // unique listener per thread 563 Grammar g = new Grammar( 564 "parser grammar t;\n"+ 565 "scope s {\n" + 566 " int n;\n" + 567 "}\n" + 568 "a : s=b \n" + 569 " ;\n" + 570 "b : ;\n"); 571 572 Object expectedArg = "s"; 573 int expectedMsgID = ErrorManager.MSG_SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE; 574 GrammarSemanticsMessage expectedMessage = 575 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 576 checkGrammarSemanticsError(equeue, expectedMessage); 577 } 578 testLabelAndRuleNameConflict()579 @Test public void testLabelAndRuleNameConflict() throws Exception { 580 ErrorQueue equeue = new ErrorQueue(); 581 ErrorManager.setErrorListener(equeue); // unique listener per thread 582 Grammar g = new Grammar( 583 "parser grammar t;\n"+ 584 "a : c=b \n" + 585 " ;\n" + 586 "b : ;\n" + 587 "c : ;\n"); 588 589 Object expectedArg = "c"; 590 int expectedMsgID = ErrorManager.MSG_LABEL_CONFLICTS_WITH_RULE; 591 GrammarSemanticsMessage expectedMessage = 592 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 593 checkGrammarSemanticsError(equeue, expectedMessage); 594 } 595 testLabelAndTokenNameConflict()596 @Test public void testLabelAndTokenNameConflict() throws Exception { 597 ErrorQueue equeue = new ErrorQueue(); 598 ErrorManager.setErrorListener(equeue); // unique listener per thread 599 Grammar g = new Grammar( 600 "parser grammar t;\n"+ 601 "a : ID=b \n" + 602 " ;\n" + 603 "b : ID ;\n" + 604 "c : ;\n"); 605 606 Object expectedArg = "ID"; 607 int expectedMsgID = ErrorManager.MSG_LABEL_CONFLICTS_WITH_TOKEN; 608 GrammarSemanticsMessage expectedMessage = 609 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 610 checkGrammarSemanticsError(equeue, expectedMessage); 611 } 612 testLabelAndArgConflict()613 @Test public void testLabelAndArgConflict() throws Exception { 614 ErrorQueue equeue = new ErrorQueue(); 615 ErrorManager.setErrorListener(equeue); // unique listener per thread 616 Grammar g = new Grammar( 617 "parser grammar t;\n"+ 618 "a[int i] returns [int x]: i=ID \n" + 619 " ;\n"); 620 621 Object expectedArg = "i"; 622 int expectedMsgID = ErrorManager.MSG_LABEL_CONFLICTS_WITH_RULE_ARG_RETVAL; 623 GrammarSemanticsMessage expectedMessage = 624 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 625 checkGrammarSemanticsError(equeue, expectedMessage); 626 } 627 testLabelAndParameterConflict()628 @Test public void testLabelAndParameterConflict() throws Exception { 629 ErrorQueue equeue = new ErrorQueue(); 630 ErrorManager.setErrorListener(equeue); // unique listener per thread 631 Grammar g = new Grammar( 632 "parser grammar t;\n"+ 633 "a[int i] returns [int x]: x=ID \n" + 634 " ;\n"); 635 636 Object expectedArg = "x"; 637 int expectedMsgID = ErrorManager.MSG_LABEL_CONFLICTS_WITH_RULE_ARG_RETVAL; 638 GrammarSemanticsMessage expectedMessage = 639 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 640 checkGrammarSemanticsError(equeue, expectedMessage); 641 } 642 testLabelRuleScopeConflict()643 @Test public void testLabelRuleScopeConflict() throws Exception { 644 ErrorQueue equeue = new ErrorQueue(); 645 ErrorManager.setErrorListener(equeue); // unique listener per thread 646 Grammar g = new Grammar( 647 "parser grammar t;\n"+ 648 "a\n" + 649 "scope {" + 650 " int n;" + 651 "}\n" + 652 " : n=ID\n" + 653 " ;\n"); 654 655 Object expectedArg = "n"; 656 Object expectedArg2 = "a"; 657 int expectedMsgID = ErrorManager.MSG_LABEL_CONFLICTS_WITH_RULE_SCOPE_ATTRIBUTE; 658 GrammarSemanticsMessage expectedMessage = 659 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 660 checkGrammarSemanticsError(equeue, expectedMessage); 661 } 662 testRuleScopeArgConflict()663 @Test public void testRuleScopeArgConflict() throws Exception { 664 ErrorQueue equeue = new ErrorQueue(); 665 ErrorManager.setErrorListener(equeue); // unique listener per thread 666 Grammar g = new Grammar( 667 "parser grammar t;\n"+ 668 "a[int n]\n" + 669 "scope {" + 670 " int n;" + 671 "}\n" + 672 " : \n" + 673 " ;\n"); 674 675 Object expectedArg = "n"; 676 Object expectedArg2 = "a"; 677 int expectedMsgID = ErrorManager.MSG_ATTRIBUTE_CONFLICTS_WITH_RULE_ARG_RETVAL; 678 GrammarSemanticsMessage expectedMessage = 679 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 680 checkGrammarSemanticsError(equeue, expectedMessage); 681 } 682 testRuleScopeReturnValueConflict()683 @Test public void testRuleScopeReturnValueConflict() throws Exception { 684 ErrorQueue equeue = new ErrorQueue(); 685 ErrorManager.setErrorListener(equeue); // unique listener per thread 686 Grammar g = new Grammar( 687 "parser grammar t;\n"+ 688 "a returns [int n]\n" + 689 "scope {" + 690 " int n;" + 691 "}\n" + 692 " : \n" + 693 " ;\n"); 694 695 Object expectedArg = "n"; 696 Object expectedArg2 = "a"; 697 int expectedMsgID = ErrorManager.MSG_ATTRIBUTE_CONFLICTS_WITH_RULE_ARG_RETVAL; 698 GrammarSemanticsMessage expectedMessage = 699 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 700 checkGrammarSemanticsError(equeue, expectedMessage); 701 } 702 testRuleScopeRuleNameConflict()703 @Test public void testRuleScopeRuleNameConflict() throws Exception { 704 ErrorQueue equeue = new ErrorQueue(); 705 ErrorManager.setErrorListener(equeue); // unique listener per thread 706 Grammar g = new Grammar( 707 "parser grammar t;\n"+ 708 "a\n" + 709 "scope {" + 710 " int a;" + 711 "}\n" + 712 " : \n" + 713 " ;\n"); 714 715 Object expectedArg = "a"; 716 Object expectedArg2 = null; 717 int expectedMsgID = ErrorManager.MSG_ATTRIBUTE_CONFLICTS_WITH_RULE; 718 GrammarSemanticsMessage expectedMessage = 719 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 720 checkGrammarSemanticsError(equeue, expectedMessage); 721 } 722 testBadGrammarOption()723 @Test public void testBadGrammarOption() throws Exception { 724 ErrorQueue equeue = new ErrorQueue(); 725 ErrorManager.setErrorListener(equeue); // unique listener per thread 726 Tool antlr = newTool(); 727 Grammar g = new Grammar(antlr, 728 "grammar t;\n"+ 729 "options {foo=3; language=Java;}\n" + 730 "a : 'a';\n"); 731 732 Object expectedArg = "foo"; 733 int expectedMsgID = ErrorManager.MSG_ILLEGAL_OPTION; 734 GrammarSemanticsMessage expectedMessage = 735 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 736 checkGrammarSemanticsError(equeue, expectedMessage); 737 } 738 testBadRuleOption()739 @Test public void testBadRuleOption() throws Exception { 740 ErrorQueue equeue = new ErrorQueue(); 741 ErrorManager.setErrorListener(equeue); // unique listener per thread 742 Grammar g = new Grammar( 743 "grammar t;\n"+ 744 "a\n"+ 745 "options {k=3; tokenVocab=blort;}\n" + 746 " : 'a';\n"); 747 748 Object expectedArg = "tokenVocab"; 749 int expectedMsgID = ErrorManager.MSG_ILLEGAL_OPTION; 750 GrammarSemanticsMessage expectedMessage = 751 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 752 checkGrammarSemanticsError(equeue, expectedMessage); 753 } 754 testBadSubRuleOption()755 @Test public void testBadSubRuleOption() throws Exception { 756 ErrorQueue equeue = new ErrorQueue(); 757 ErrorManager.setErrorListener(equeue); // unique listener per thread 758 Grammar g = new Grammar( 759 "grammar t;\n"+ 760 "a : ( options {k=3; language=Java;}\n" + 761 " : 'a'\n" + 762 " | 'b'\n" + 763 " )\n" + 764 " ;\n"); 765 Object expectedArg = "language"; 766 int expectedMsgID = ErrorManager.MSG_ILLEGAL_OPTION; 767 GrammarSemanticsMessage expectedMessage = 768 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 769 checkGrammarSemanticsError(equeue, expectedMessage); 770 } 771 testTokenVocabStringUsedInLexer()772 @Test public void testTokenVocabStringUsedInLexer() throws Exception { 773 ErrorQueue equeue = new ErrorQueue(); 774 ErrorManager.setErrorListener(equeue); 775 String tokens = 776 "';'=4\n"; 777 mkdir(tmpdir); 778 writeFile(tmpdir, "T.tokens", tokens); 779 780 String importer = 781 "lexer grammar B; \n" + 782 "options\t{tokenVocab=T;} \n" + 783 "SEMI:';' ; \n" ; 784 writeFile(tmpdir, "B.g", importer); 785 Tool antlr = newTool(new String[] {"-lib", tmpdir}); 786 CompositeGrammar composite = new CompositeGrammar(); 787 Grammar g = new Grammar(antlr,tmpdir+"/B.g",composite); 788 g.parseAndBuildAST(); 789 g.composite.assignTokenTypes(); 790 791 String expectedTokenIDToTypeMap = "[SEMI=4]"; 792 String expectedStringLiteralToTypeMap = "{';'=4}"; 793 String expectedTypeToTokenList = "[SEMI]"; 794 795 assertEquals(expectedTokenIDToTypeMap, 796 realElements(g.composite.tokenIDToTypeMap).toString()); 797 assertEquals(expectedStringLiteralToTypeMap, g.composite.stringLiteralToTypeMap.toString()); 798 assertEquals(expectedTypeToTokenList, 799 realElements(g.composite.typeToTokenList).toString()); 800 801 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 802 } 803 testTokenVocabStringUsedInCombined()804 @Test public void testTokenVocabStringUsedInCombined() throws Exception { 805 ErrorQueue equeue = new ErrorQueue(); 806 ErrorManager.setErrorListener(equeue); 807 String tokens = 808 "';'=4\n"; 809 mkdir(tmpdir); 810 writeFile(tmpdir, "T.tokens", tokens); 811 812 String importer = 813 "grammar B; \n" + 814 "options\t{tokenVocab=T;} \n" + 815 "SEMI:';' ; \n" ; 816 writeFile(tmpdir, "B.g", importer); 817 Tool antlr = newTool(new String[] {"-lib", tmpdir}); 818 CompositeGrammar composite = new CompositeGrammar(); 819 Grammar g = new Grammar(antlr,tmpdir+"/B.g",composite); 820 g.parseAndBuildAST(); 821 g.composite.assignTokenTypes(); 822 823 String expectedTokenIDToTypeMap = "[SEMI=4]"; 824 String expectedStringLiteralToTypeMap = "{';'=4}"; 825 String expectedTypeToTokenList = "[SEMI]"; 826 827 assertEquals(expectedTokenIDToTypeMap, 828 realElements(g.composite.tokenIDToTypeMap).toString()); 829 assertEquals(expectedStringLiteralToTypeMap, g.composite.stringLiteralToTypeMap.toString()); 830 assertEquals(expectedTypeToTokenList, 831 realElements(g.composite.typeToTokenList).toString()); 832 833 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 834 } 835 checkPlusEqualsLabels(Grammar g, String ruleName, String tokenLabelsStr, String ruleLabelsStr)836 protected void checkPlusEqualsLabels(Grammar g, 837 String ruleName, 838 String tokenLabelsStr, 839 String ruleLabelsStr) 840 throws Exception 841 { 842 // make sure expected += labels are there 843 Rule r = g.getRule(ruleName); 844 StringTokenizer st = new StringTokenizer(tokenLabelsStr, ", "); 845 Set tokenLabels = null; 846 while ( st.hasMoreTokens() ) { 847 if ( tokenLabels==null ) { 848 tokenLabels = new HashSet(); 849 } 850 String labelName = st.nextToken(); 851 tokenLabels.add(labelName); 852 } 853 Set ruleLabels = null; 854 if ( ruleLabelsStr!=null ) { 855 st = new StringTokenizer(ruleLabelsStr, ", "); 856 ruleLabels = new HashSet(); 857 while ( st.hasMoreTokens() ) { 858 String labelName = st.nextToken(); 859 ruleLabels.add(labelName); 860 } 861 } 862 assertTrue("token += labels mismatch; "+tokenLabels+"!="+r.tokenListLabels, 863 (tokenLabels!=null && r.tokenListLabels!=null) || 864 (tokenLabels==null && r.tokenListLabels==null)); 865 assertTrue("rule += labels mismatch; "+ruleLabels+"!="+r.ruleListLabels, 866 (ruleLabels!=null && r.ruleListLabels!=null) || 867 (ruleLabels==null && r.ruleListLabels==null)); 868 if ( tokenLabels!=null ) { 869 assertEquals(tokenLabels, r.tokenListLabels.keySet()); 870 } 871 if ( ruleLabels!=null ) { 872 assertEquals(ruleLabels, r.ruleListLabels.keySet()); 873 } 874 } 875 checkSymbols(Grammar g, String rulesStr, String tokensStr)876 protected void checkSymbols(Grammar g, 877 String rulesStr, 878 String tokensStr) 879 throws Exception 880 { 881 Set tokens = g.getTokenDisplayNames(); 882 883 // make sure expected tokens are there 884 StringTokenizer st = new StringTokenizer(tokensStr, ", "); 885 while ( st.hasMoreTokens() ) { 886 String tokenName = st.nextToken(); 887 assertTrue("token "+tokenName+" expected", 888 g.getTokenType(tokenName)!=Label.INVALID); 889 tokens.remove(tokenName); 890 } 891 // make sure there are not any others (other than <EOF> etc...) 892 for (Iterator iter = tokens.iterator(); iter.hasNext();) { 893 String tokenName = (String) iter.next(); 894 assertTrue("unexpected token name "+tokenName, 895 g.getTokenType(tokenName)<Label.MIN_TOKEN_TYPE); 896 } 897 898 // make sure all expected rules are there 899 st = new StringTokenizer(rulesStr, ", "); 900 int n = 0; 901 while ( st.hasMoreTokens() ) { 902 String ruleName = st.nextToken(); 903 assertNotNull("rule "+ruleName+" expected", g.getRule(ruleName)); 904 n++; 905 } 906 Collection rules = g.getRules(); 907 //System.out.println("rules="+rules); 908 // make sure there are no extra rules 909 assertEquals("number of rules mismatch; expecting "+n+"; found "+rules.size(), n, rules.size()); 910 911 } 912 913 } 914