Package org.antlr.test

Source Code of org.antlr.test.TestSymbolDefinitions

/*
* [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.*;

import static org.junit.Assert.*;

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<String> 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<String> tokenLabels = null;
    while ( st.hasMoreTokens() ) {
      if ( tokenLabels==null ) {
        tokenLabels = new HashSet<String>();
      }
      String labelName = st.nextToken();
      tokenLabels.add(labelName);
    }
    Set<String> ruleLabels = null;
    if ( ruleLabelsStr!=null ) {
      st = new StringTokenizer(ruleLabelsStr, ", ");
      ruleLabels = new HashSet<String>();
      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<String> 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 (String tokenName : tokens) {
      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<Rule> 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());

  }

}
TOP

Related Classes of org.antlr.test.TestSymbolDefinitions

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.