/*
 * [The "BSD license"]
 *  Copyright (c) 2010 Terence Parr
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *  1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.antlr.test;

import org.antlr.Tool;
import org.antlr.analysis.Label;
import org.antlr.codegen.CodeGenerator;
import org.stringtemplate.v4.ST;
import org.antlr.tool.*;
import org.junit.Test;

import java.util.*;

public class TestSymbolDefinitions extends BaseTest {

	/** Public default constructor used by TestRig */
	public TestSymbolDefinitions() {
	}

	@Test public void testParserSimpleTokens() throws Exception {
		Grammar g = new Grammar(
				"parser grammar t;\n"+
				"a : A | B;\n" +
				"b : C ;");
		String rules = "a, b";
		String tokenNames = "A, B, C";
		checkSymbols(g, rules, tokenNames);
	}

	@Test public void testParserTokensSection() throws Exception {
		Grammar g = new Grammar(
				"parser grammar t;\n" +
				"tokens {\n" +
				"  C;\n" +
				"  D;" +
				"}\n"+
				"a : A | B;\n" +
				"b : C ;");
		String rules = "a, b";
		String tokenNames = "A, B, C, D";
		checkSymbols(g, rules, tokenNames);
	}

	@Test public void testLexerTokensSection() throws Exception {
		Grammar g = new Grammar(
				"lexer grammar t;\n" +
				"tokens {\n" +
				"  C;\n" +
				"  D;" +
				"}\n"+
				"A : 'a';\n" +
				"C : 'c' ;");
		String rules = "A, C, Tokens";
		String tokenNames = "A, C, D";
		checkSymbols(g, rules, tokenNames);
	}

	@Test public void testTokensSectionWithAssignmentSection() throws Exception {
		Grammar g = new Grammar(
				"grammar t;\n" +
				"tokens {\n" +
				"  C='c';\n" +
				"  D;" +
				"}\n"+
				"a : A | B;\n" +
				"b : C ;");
		String rules = "a, b";
		String tokenNames = "A, B, C, D, 'c'";
		checkSymbols(g, rules, tokenNames);
	}

	@Test public void testCombinedGrammarLiterals() throws Exception {
		Grammar g = new Grammar(
				"grammar t;\n"+
				"a : 'begin' b 'end';\n" +
				"b : C ';' ;\n" +
				"ID : 'a' ;\n" +
				"FOO : 'foo' ;\n" +  // "foo" is not a token name
				"C : 'c' ;\n");        // nor is 'c'
		String rules = "a, b";
		String tokenNames = "C, FOO, ID, 'begin', 'end', ';'";
		checkSymbols(g, rules, tokenNames);
	}

	@Test public void testLiteralInParserAndLexer() throws Exception {
		// 'x' is token and char in lexer rule
		Grammar g = new Grammar(
				"grammar t;\n" +
				"a : 'x' E ; \n" +
				"E: 'x' '0' ;\n");        // nor is 'c'
		String literals = "['x']";
		String foundLiterals = g.getStringLiterals().toString();
		assertEquals(literals, foundLiterals);

		String implicitLexer =
			"lexer grammar t;" + newline +
			"T__5 : 'x' ;" + newline +
			"" + newline +
			"// $ANTLR src \"<string>\" 3" + newline +
			"E: 'x' '0' ;";
		assertEquals(implicitLexer, g.getLexerGrammar());
	}

	@Test public void testCombinedGrammarWithRefToLiteralButNoTokenIDRef() throws Exception {
		Grammar g = new Grammar(
				"grammar t;\n"+
				"a : 'a' ;\n" +
				"A : 'a' ;\n");
		String rules = "a";
		String tokenNames = "A, 'a'";
		checkSymbols(g, rules, tokenNames);
	}

	@Test public void testSetDoesNotMissTokenAliases() throws Exception {
		Grammar g = new Grammar(
				"grammar t;\n"+
				"a : 'a'|'b' ;\n" +
				"A : 'a' ;\n" +
				"B : 'b' ;\n");
		String rules = "a";
		String tokenNames = "A, 'a', B, 'b'";
		checkSymbols(g, rules, tokenNames);
	}

	@Test public void testSimplePlusEqualLabel() throws Exception {
		Grammar g = new Grammar(
				"parser grammar t;\n"+
				"a : ids+=ID ( COMMA ids+=ID )* ;\n");
		String rule = "a";
		String tokenLabels = "ids";
		String ruleLabels = null;
		checkPlusEqualsLabels(g, rule, tokenLabels, ruleLabels);
	}

	@Test public void testMixedPlusEqualLabel() throws Exception {
		Grammar g = new Grammar(
				"grammar t;\n"+
				"options {output=AST;}\n" +
				"a : id+=ID ( ',' e+=expr )* ;\n" +
				"expr : 'e';\n" +
				"ID : 'a';\n");
		String rule = "a";
		String tokenLabels = "id";
		String ruleLabels = "e";
		checkPlusEqualsLabels(g, rule, tokenLabels, ruleLabels);
	}

	// T E S T  L I T E R A L  E S C A P E S

	@Test public void testParserCharLiteralWithEscape() throws Exception {
		Grammar g = new Grammar(
				"grammar t;\n"+
				"a : '\\n';\n");
		Set literals = g.getStringLiterals();
		// must store literals how they appear in the antlr grammar
		assertEquals("'\\n'", literals.toArray()[0]);
	}

	@Test public void testTokenInTokensSectionAndTokenRuleDef() throws Exception {
		// this must return A not I to the parser; calling a nonfragment rule
		// from a nonfragment rule does not set the overall token.
		String grammar =
			"grammar P;\n" +
			"tokens { B='}'; }\n"+
			"a : A B {System.out.println(input);} ;\n"+
			"A : 'a' ;\n" +
			"B : '}' ;\n"+
			"WS : (' '|'\\n') {$channel=HIDDEN;} ;";
		String found = execParser("P.g", grammar, "PParser", "PLexer",
								  "a", "a}", false);
		assertEquals("a}\n", found);
	}

	@Test public void testTokenInTokensSectionAndTokenRuleDef2() throws Exception {
		// this must return A not I to the parser; calling a nonfragment rule
		// from a nonfragment rule does not set the overall token.
		String grammar =
			"grammar P;\n" +
			"tokens { B='}'; }\n"+
			"a : A '}' {System.out.println(input);} ;\n"+
			"A : 'a' ;\n" +
			"B : '}' {/* */} ;\n"+
			"WS : (' '|'\\n') {$channel=HIDDEN;} ;";
		String found = execParser("P.g", grammar, "PParser", "PLexer",
								  "a", "a}", false);
		assertEquals("a}\n", found);
	}


	@Test public void testRefToRuleWithNoReturnValue() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue);

		String grammarStr =
			"grammar P;\n" +
			"a : x=b ;\n" +
			"b : B ;\n" +
			"B : 'b' ;\n";
		Grammar g = new Grammar(grammarStr);

		Tool antlr = newTool();
		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
		g.setCodeGenerator(generator);
		ST recogST = generator.genRecognizer();
		String code = recogST.render();
		assertTrue("not expecting label", code.indexOf("x=b();")<0);

		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
	}

	// T E S T  E R R O R S

	@Test public void testParserStringLiterals() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue);
		Grammar g = new Grammar(
				"parser grammar t;\n"+
				"a : 'begin' b ;\n" +
				"b : C ;");
		Object expectedArg = "'begin'";
		int expectedMsgID = ErrorManager.MSG_LITERAL_NOT_ASSOCIATED_WITH_LEXER_RULE;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testParserCharLiterals() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue);
		Grammar g = new Grammar(
				"parser grammar t;\n"+
				"a : '(' b ;\n" +
				"b : C ;");
		Object expectedArg = "'('";
		int expectedMsgID = ErrorManager.MSG_LITERAL_NOT_ASSOCIATED_WITH_LEXER_RULE;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testEmptyNotChar() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue);
		Grammar g = new Grammar(
				"grammar foo;\n" +
				"a : (~'x')+ ;\n");
		g.buildNFA();
		Object expectedArg = "'x'";
		int expectedMsgID = ErrorManager.MSG_EMPTY_COMPLEMENT;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testEmptyNotToken() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue);
		Grammar g = new Grammar(
				"grammar foo;\n" +
				"a : (~A)+ ;\n");
		g.buildNFA();
		Object expectedArg = "A";
		int expectedMsgID = ErrorManager.MSG_EMPTY_COMPLEMENT;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testEmptyNotSet() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue);
		Grammar g = new Grammar(
				"grammar foo;\n" +
				"a : (~(A|B))+ ;\n");
		g.buildNFA();
		Object expectedArg = null;
		int expectedMsgID = ErrorManager.MSG_EMPTY_COMPLEMENT;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testStringLiteralInParserTokensSection() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
				"parser grammar t;\n" +
				"tokens {\n" +
				"  B='begin';\n" +
				"}\n"+
				"a : A B;\n" +
				"b : C ;");
		Object expectedArg = "'begin'";
		int expectedMsgID = ErrorManager.MSG_LITERAL_NOT_ASSOCIATED_WITH_LEXER_RULE;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testCharLiteralInParserTokensSection() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
				"parser grammar t;\n" +
				"tokens {\n" +
				"  B='(';\n" +
				"}\n"+
				"a : A B;\n" +
				"b : C ;");
		Object expectedArg = "'('";
		int expectedMsgID = ErrorManager.MSG_LITERAL_NOT_ASSOCIATED_WITH_LEXER_RULE;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testCharLiteralInLexerTokensSection() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
				"lexer grammar t;\n" +
				"tokens {\n" +
				"  B='(';\n" +
				"}\n"+
				"ID : 'a';\n");
		Object expectedArg = "'('";
		int expectedMsgID = ErrorManager.MSG_CANNOT_ALIAS_TOKENS_IN_LEXER;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testRuleRedefinition() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
				"parser grammar t;\n"+
				"a : A | B;\n" +
				"a : C ;");

		Object expectedArg = "a";
		int expectedMsgID = ErrorManager.MSG_RULE_REDEFINITION;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testLexerRuleRedefinition() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
				"lexer grammar t;\n"+
				"ID : 'a' ;\n" +
				"ID : 'd' ;");

		Object expectedArg = "ID";
		int expectedMsgID = ErrorManager.MSG_RULE_REDEFINITION;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testCombinedRuleRedefinition() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
				"grammar t;\n"+
				"x : ID ;\n" +
				"ID : 'a' ;\n" +
				"x : ID ID ;");

		Object expectedArg = "x";
		int expectedMsgID = ErrorManager.MSG_RULE_REDEFINITION;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testUndefinedToken() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
				"grammar t;\n"+
				"x : ID ;");

		Object expectedArg = "ID";
		int expectedMsgID = ErrorManager.MSG_NO_TOKEN_DEFINITION;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsWarning(equeue, expectedMessage);
	}

	@Test public void testUndefinedTokenOkInParser() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
				"parser grammar t;\n"+
				"x : ID ;");
		assertEquals("should not be an error", 0, equeue.errors.size());
	}

	@Test public void testUndefinedRule() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
				"grammar t;\n"+
				"x : r ;");

		Object expectedArg = "r";
		int expectedMsgID = ErrorManager.MSG_UNDEFINED_RULE_REF;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testLexerRuleInParser() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
				"parser grammar t;\n"+
				"X : ;");

		Object expectedArg = "X";
		int expectedMsgID = ErrorManager.MSG_LEXER_RULES_NOT_ALLOWED;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testParserRuleInLexer() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
				"lexer grammar t;\n"+
				"a : ;");

		Object expectedArg = "a";
		int expectedMsgID = ErrorManager.MSG_PARSER_RULES_NOT_ALLOWED;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testRuleScopeConflict() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
			"grammar t;\n"+
			"scope a {\n" +
			"  int n;\n" +
			"}\n" +
			"a : \n" +
			"  ;\n");

		Object expectedArg = "a";
		int expectedMsgID = ErrorManager.MSG_SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testTokenRuleScopeConflict() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
			"grammar t;\n"+
			"scope ID {\n" +
			"  int n;\n" +
			"}\n" +
			"ID : 'a'\n" +
			"  ;\n");

		Object expectedArg = "ID";
		int expectedMsgID = ErrorManager.MSG_SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testTokenScopeConflict() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
			"grammar t;\n"+
			"tokens { ID; }\n"+
			"scope ID {\n" +
			"  int n;\n" +
			"}\n" +
			"a : \n" +
			"  ;\n");

		Object expectedArg = "ID";
		int expectedMsgID = ErrorManager.MSG_SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testTokenRuleScopeConflictInLexerGrammar() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
			"lexer grammar t;\n"+
			"scope ID {\n" +
			"  int n;\n" +
			"}\n" +
			"ID : 'a'\n" +
			"  ;\n");

		Object expectedArg = "ID";
		int expectedMsgID = ErrorManager.MSG_SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testTokenLabelScopeConflict() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
			"parser grammar t;\n"+
			"scope s {\n" +
			"  int n;\n" +
			"}\n" +
			"a : s=ID \n" +
			"  ;\n");

		Object expectedArg = "s";
		int expectedMsgID = ErrorManager.MSG_SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testRuleLabelScopeConflict() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
			"parser grammar t;\n"+
			"scope s {\n" +
			"  int n;\n" +
			"}\n" +
			"a : s=b \n" +
			"  ;\n" +
			"b : ;\n");

		Object expectedArg = "s";
		int expectedMsgID = ErrorManager.MSG_SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testLabelAndRuleNameConflict() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
			"parser grammar t;\n"+
			"a : c=b \n" +
			"  ;\n" +
			"b : ;\n" +
			"c : ;\n");

		Object expectedArg = "c";
		int expectedMsgID = ErrorManager.MSG_LABEL_CONFLICTS_WITH_RULE;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testLabelAndTokenNameConflict() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
			"parser grammar t;\n"+
			"a : ID=b \n" +
			"  ;\n" +
			"b : ID ;\n" +
			"c : ;\n");

		Object expectedArg = "ID";
		int expectedMsgID = ErrorManager.MSG_LABEL_CONFLICTS_WITH_TOKEN;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testLabelAndArgConflict() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
			"parser grammar t;\n"+
			"a[int i] returns [int x]: i=ID \n" +
			"  ;\n");

		Object expectedArg = "i";
		int expectedMsgID = ErrorManager.MSG_LABEL_CONFLICTS_WITH_RULE_ARG_RETVAL;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testLabelAndParameterConflict() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
			"parser grammar t;\n"+
			"a[int i] returns [int x]: x=ID \n" +
			"  ;\n");

		Object expectedArg = "x";
		int expectedMsgID = ErrorManager.MSG_LABEL_CONFLICTS_WITH_RULE_ARG_RETVAL;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testLabelRuleScopeConflict() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
			"parser grammar t;\n"+
			"a\n" +
			"scope {" +
			"  int n;" +
			"}\n" +
			"  : n=ID\n" +
			"  ;\n");

		Object expectedArg = "n";
		Object expectedArg2 = "a";
		int expectedMsgID = ErrorManager.MSG_LABEL_CONFLICTS_WITH_RULE_SCOPE_ATTRIBUTE;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testRuleScopeArgConflict() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
			"parser grammar t;\n"+
			"a[int n]\n" +
			"scope {" +
			"  int n;" +
			"}\n" +
			"  : \n" +
			"  ;\n");

		Object expectedArg = "n";
		Object expectedArg2 = "a";
		int expectedMsgID = ErrorManager.MSG_ATTRIBUTE_CONFLICTS_WITH_RULE_ARG_RETVAL;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testRuleScopeReturnValueConflict() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
			"parser grammar t;\n"+
			"a returns [int n]\n" +
			"scope {" +
			"  int n;" +
			"}\n" +
			"  : \n" +
			"  ;\n");

		Object expectedArg = "n";
		Object expectedArg2 = "a";
		int expectedMsgID = ErrorManager.MSG_ATTRIBUTE_CONFLICTS_WITH_RULE_ARG_RETVAL;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testRuleScopeRuleNameConflict() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
			"parser grammar t;\n"+
			"a\n" +
			"scope {" +
			"  int a;" +
			"}\n" +
			"  : \n" +
			"  ;\n");

		Object expectedArg = "a";
		Object expectedArg2 = null;
		int expectedMsgID = ErrorManager.MSG_ATTRIBUTE_CONFLICTS_WITH_RULE;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testBadGrammarOption() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Tool antlr = newTool();
		Grammar g = new Grammar(antlr,
								"grammar t;\n"+
								"options {foo=3; language=Java;}\n" +
								"a : 'a';\n");

		Object expectedArg = "foo";
		int expectedMsgID = ErrorManager.MSG_ILLEGAL_OPTION;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testBadRuleOption() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
				"grammar t;\n"+
				"a\n"+
				"options {k=3; tokenVocab=blort;}\n" +
				"  : 'a';\n");

		Object expectedArg = "tokenVocab";
		int expectedMsgID = ErrorManager.MSG_ILLEGAL_OPTION;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testBadSubRuleOption() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue); // unique listener per thread
		Grammar g = new Grammar(
				"grammar t;\n"+
				"a : ( options {k=3; language=Java;}\n" +
				"    : 'a'\n" +
				"    | 'b'\n" +
				"    )\n" +
				"  ;\n");
		Object expectedArg = "language";
		int expectedMsgID = ErrorManager.MSG_ILLEGAL_OPTION;
		GrammarSemanticsMessage expectedMessage =
			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
		checkGrammarSemanticsError(equeue, expectedMessage);
	}

	@Test public void testTokenVocabStringUsedInLexer() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue);
		String tokens =
			"';'=4\n";
        mkdir(tmpdir);
        writeFile(tmpdir, "T.tokens", tokens);

		String importer =
			"lexer grammar B; \n" +
			"options\t{tokenVocab=T;} \n" +
			"SEMI:';' ; \n" ;
		writeFile(tmpdir, "B.g", importer);
		Tool antlr = newTool(new String[] {"-lib", tmpdir});
		CompositeGrammar composite = new CompositeGrammar();
		Grammar g = new Grammar(antlr,tmpdir+"/B.g",composite);
		g.parseAndBuildAST();
		g.composite.assignTokenTypes();

		String expectedTokenIDToTypeMap = "[SEMI=4]";
		String expectedStringLiteralToTypeMap = "{';'=4}";
		String expectedTypeToTokenList = "[SEMI]";

		assertEquals(expectedTokenIDToTypeMap,
					 realElements(g.composite.tokenIDToTypeMap).toString());
		assertEquals(expectedStringLiteralToTypeMap, g.composite.stringLiteralToTypeMap.toString());
		assertEquals(expectedTypeToTokenList,
					 realElements(g.composite.typeToTokenList).toString());

		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
	}

	@Test public void testTokenVocabStringUsedInCombined() throws Exception {
		ErrorQueue equeue = new ErrorQueue();
		ErrorManager.setErrorListener(equeue);
		String tokens =
			"';'=4\n";
        mkdir(tmpdir);
		writeFile(tmpdir, "T.tokens", tokens);

		String importer =
			"grammar B; \n" +
			"options\t{tokenVocab=T;} \n" +
			"SEMI:';' ; \n" ;
		writeFile(tmpdir, "B.g", importer);
		Tool antlr = newTool(new String[] {"-lib", tmpdir});
		CompositeGrammar composite = new CompositeGrammar();
		Grammar g = new Grammar(antlr,tmpdir+"/B.g",composite);
		g.parseAndBuildAST();
		g.composite.assignTokenTypes();

		String expectedTokenIDToTypeMap = "[SEMI=4]";
		String expectedStringLiteralToTypeMap = "{';'=4}";
		String expectedTypeToTokenList = "[SEMI]";

		assertEquals(expectedTokenIDToTypeMap,
					 realElements(g.composite.tokenIDToTypeMap).toString());
		assertEquals(expectedStringLiteralToTypeMap, g.composite.stringLiteralToTypeMap.toString());
		assertEquals(expectedTypeToTokenList,
					 realElements(g.composite.typeToTokenList).toString());

		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
	}

	protected void checkPlusEqualsLabels(Grammar g,
										 String ruleName,
										 String tokenLabelsStr,
										 String ruleLabelsStr)
		throws Exception
	{
		// make sure expected += labels are there
		Rule r = g.getRule(ruleName);
		StringTokenizer st = new StringTokenizer(tokenLabelsStr, ", ");
		Set tokenLabels = null;
		while ( st.hasMoreTokens() ) {
			if ( tokenLabels==null ) {
				tokenLabels = new HashSet();
			}
			String labelName = st.nextToken();
			tokenLabels.add(labelName);
		}
		Set ruleLabels = null;
		if ( ruleLabelsStr!=null ) {
			st = new StringTokenizer(ruleLabelsStr, ", ");
			ruleLabels = new HashSet();
			while ( st.hasMoreTokens() ) {
				String labelName = st.nextToken();
				ruleLabels.add(labelName);
			}
		}
		assertTrue("token += labels mismatch; "+tokenLabels+"!="+r.tokenListLabels,
				   (tokenLabels!=null && r.tokenListLabels!=null) ||
				   (tokenLabels==null && r.tokenListLabels==null));
		assertTrue("rule += labels mismatch; "+ruleLabels+"!="+r.ruleListLabels,
				   (ruleLabels!=null && r.ruleListLabels!=null) ||
				   (ruleLabels==null && r.ruleListLabels==null));
		if ( tokenLabels!=null ) {
			assertEquals(tokenLabels, r.tokenListLabels.keySet());
		}
		if ( ruleLabels!=null ) {
			assertEquals(ruleLabels, r.ruleListLabels.keySet());
		}
	}

	protected void checkSymbols(Grammar g,
								String rulesStr,
								String tokensStr)
		throws Exception
	{
		Set tokens = g.getTokenDisplayNames();

		// make sure expected tokens are there
		StringTokenizer st = new StringTokenizer(tokensStr, ", ");
		while ( st.hasMoreTokens() ) {
			String tokenName = st.nextToken();
			assertTrue("token "+tokenName+" expected",
					   g.getTokenType(tokenName)!=Label.INVALID);
			tokens.remove(tokenName);
		}
		// make sure there are not any others (other than <EOF> etc...)
		for (Iterator iter = tokens.iterator(); iter.hasNext();) {
			String tokenName = (String) iter.next();
			assertTrue("unexpected token name "+tokenName,
					   g.getTokenType(tokenName)<Label.MIN_TOKEN_TYPE);
		}

		// make sure all expected rules are there
		st = new StringTokenizer(rulesStr, ", ");
		int n = 0;
		while ( st.hasMoreTokens() ) {
			String ruleName = st.nextToken();
			assertNotNull("rule "+ruleName+" expected", g.getRule(ruleName));
			n++;
		}
		Collection rules = g.getRules();
		//System.out.println("rules="+rules);
		// make sure there are no extra rules
		assertEquals("number of rules mismatch; expecting "+n+"; found "+rules.size(), n, rules.size());

	}

}
