Package org.antlr.v4.test

Source Code of org.antlr.v4.test.TestATNInterpreter

/*
* [The "BSD license"]
*  Copyright (c) 2012 Terence Parr
*  Copyright (c) 2012 Sam Harwell
*  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.v4.test;

import org.antlr.v4.automata.ParserATNFactory;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.NoViableAltException;
import org.antlr.v4.runtime.atn.ATN;
import org.antlr.v4.runtime.atn.ATNState;
import org.antlr.v4.runtime.atn.BlockStartState;
import org.antlr.v4.runtime.atn.LexerATNSimulator;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.IntegerList;
import org.antlr.v4.tool.DOTGenerator;
import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.LexerGrammar;
import org.antlr.v4.tool.Rule;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

  // NOTICE: TOKENS IN LEXER, PARSER MUST BE SAME OR TOKEN TYPE MISMATCH
  // NOTICE: TOKENS IN LEXER, PARSER MUST BE SAME OR TOKEN TYPE MISMATCH
  // NOTICE: TOKENS IN LEXER, PARSER MUST BE SAME OR TOKEN TYPE MISMATCH

public class TestATNInterpreter extends BaseTest {
  @Test public void testSimpleNoBlock() throws Exception {
    LexerGrammar lg = new LexerGrammar(
      "lexer grammar L;\n" +
      "A : 'a' ;\n" +
      "B : 'b' ;\n" +
      "C : 'c' ;\n");
    Grammar g = new Grammar(
      "parser grammar T;\n"+
      "a : A B ;");
    checkMatchedAlt(lg, g, "ab", 1);
  }

  @Test public void testSet() throws Exception {
    LexerGrammar lg = new LexerGrammar(
      "lexer grammar L;\n" +
      "A : 'a' ;\n" +
      "B : 'b' ;\n" +
      "C : 'c' ;\n");
    Grammar g = new Grammar(
      "parser grammar T;\n"+
      "tokens {A,B,C}\n" +
      "a : ~A ;");
    checkMatchedAlt(lg, g, "b", 1);
  }

  @Test public void testPEGAchillesHeel() throws Exception {
    LexerGrammar lg = new LexerGrammar(
      "lexer grammar L;\n" +
      "A : 'a' ;\n" +
      "B : 'b' ;\n" +
      "C : 'c' ;\n");
    Grammar g = new Grammar(
      "parser grammar T;\n"+
      "a : A | A B ;");
    checkMatchedAlt(lg, g, "a", 1);
    checkMatchedAlt(lg, g, "ab", 2);
    checkMatchedAlt(lg, g, "abc", 2);
  }

  @Test public void testMustTrackPreviousGoodAlt() throws Exception {
    LexerGrammar lg = new LexerGrammar(
      "lexer grammar L;\n" +
      "A : 'a' ;\n" +
      "B : 'b' ;\n" +
      "C : 'c' ;\n");
    Grammar g = new Grammar(
      "parser grammar T;\n"+
      "a : A | A B ;");

    checkMatchedAlt(lg, g, "a", 1);
    checkMatchedAlt(lg, g, "ab", 2);

    checkMatchedAlt(lg, g, "ac", 1);
    checkMatchedAlt(lg, g, "abc", 2);
  }

  @Test(expected = NoViableAltException.class)
  public void testMustTrackPreviousGoodAltWithEOF() throws Exception {
    LexerGrammar lg = new LexerGrammar(
      "lexer grammar L;\n" +
      "A : 'a' ;\n" +
      "B : 'b' ;\n" +
      "C : 'c' ;\n");
    Grammar g = new Grammar(
      "parser grammar T;\n"+
      "a : (A | A B) EOF;");

    checkMatchedAlt(lg, g, "a", 1);
    checkMatchedAlt(lg, g, "ab", 2);

    try {
      checkMatchedAlt(lg, g, "ac", 1);
    }
    catch (NoViableAltException re) {
      assertEquals(1, re.getOffendingToken().getTokenIndex());
      assertEquals(3, re.getOffendingToken().getType());
      throw re;
    }
  }

  @Test public void testMustTrackPreviousGoodAlt2() throws Exception {
    LexerGrammar lg = new LexerGrammar(
      "lexer grammar L;\n" +
      "A : 'a' ;\n" +
      "B : 'b' ;\n" +
      "C : 'c' ;\n" +
      "D : 'd' ;\n");
    Grammar g = new Grammar(
      "parser grammar T;\n"+
      "a : A | A B | A B C ;");

    checkMatchedAlt(lg, g, "a", 1);
    checkMatchedAlt(lg, g, "ab", 2);
    checkMatchedAlt(lg, g, "abc", 3);

    checkMatchedAlt(lg, g, "ad", 1);
    checkMatchedAlt(lg, g, "abd", 2);
    checkMatchedAlt(lg, g, "abcd", 3);
  }

  @Test(expected = NoViableAltException.class)
  public void testMustTrackPreviousGoodAlt2WithEOF() throws Exception {
    LexerGrammar lg = new LexerGrammar(
      "lexer grammar L;\n" +
      "A : 'a' ;\n" +
      "B : 'b' ;\n" +
      "C : 'c' ;\n" +
      "D : 'd' ;\n");
    Grammar g = new Grammar(
      "parser grammar T;\n"+
      "a : (A | A B | A B C) EOF;");

    checkMatchedAlt(lg, g, "a", 1);
    checkMatchedAlt(lg, g, "ab", 2);
    checkMatchedAlt(lg, g, "abc", 3);

    try {
      checkMatchedAlt(lg, g, "abd", 1);
    }
    catch (NoViableAltException re) {
      assertEquals(2, re.getOffendingToken().getTokenIndex());
      assertEquals(4, re.getOffendingToken().getType());
      throw re;
    }
  }

  @Test public void testMustTrackPreviousGoodAlt3() throws Exception {
    LexerGrammar lg = new LexerGrammar(
      "lexer grammar L;\n" +
      "A : 'a' ;\n" +
      "B : 'b' ;\n" +
      "C : 'c' ;\n" +
      "D : 'd' ;\n");
    Grammar g = new Grammar(
      "parser grammar T;\n"+
      "a : A B | A | A B C ;");

    checkMatchedAlt(lg, g, "a", 2);
    checkMatchedAlt(lg, g, "ab", 1);
    checkMatchedAlt(lg, g, "abc", 3);

    checkMatchedAlt(lg, g, "ad", 2);
    checkMatchedAlt(lg, g, "abd", 1);
    checkMatchedAlt(lg, g, "abcd", 3);
  }

  @Test(expected = NoViableAltException.class)
  public void testMustTrackPreviousGoodAlt3WithEOF() throws Exception {
    LexerGrammar lg = new LexerGrammar(
      "lexer grammar L;\n" +
      "A : 'a' ;\n" +
      "B : 'b' ;\n" +
      "C : 'c' ;\n" +
      "D : 'd' ;\n");
    Grammar g = new Grammar(
      "parser grammar T;\n"+
      "a : (A B | A | A B C) EOF;");

    checkMatchedAlt(lg, g, "a", 2);
    checkMatchedAlt(lg, g, "ab", 1);
    checkMatchedAlt(lg, g, "abc", 3);

    try {
      checkMatchedAlt(lg, g, "abd", 1);
    }
    catch (NoViableAltException re) {
      assertEquals(2, re.getOffendingToken().getTokenIndex());
      assertEquals(4, re.getOffendingToken().getType());
      throw re;
    }
  }

  @Test public void testAmbigAltChooseFirst() throws Exception {
    LexerGrammar lg = new LexerGrammar(
      "lexer grammar L;\n" +
      "A : 'a' ;\n" +
      "B : 'b' ;\n" +
      "C : 'c' ;\n" +
      "D : 'd' ;\n");
    Grammar g = new Grammar(
      "parser grammar T;\n"+
      "a : A B | A B ;"); // first alt
    checkMatchedAlt(lg, g, "ab", 1);
    checkMatchedAlt(lg, g, "abc", 1);
  }

  @Test public void testAmbigAltChooseFirstWithFollowingToken() throws Exception {
    LexerGrammar lg = new LexerGrammar(
      "lexer grammar L;\n" +
      "A : 'a' ;\n" +
      "B : 'b' ;\n" +
      "C : 'c' ;\n" +
      "D : 'd' ;\n");
    Grammar g = new Grammar(
      "parser grammar T;\n"+
      "a : (A B | A B) C ;"); // first alt
    checkMatchedAlt(lg, g, "abc", 1);
    checkMatchedAlt(lg, g, "abcd", 1);
  }

  @Test public void testAmbigAltChooseFirstWithFollowingToken2() throws Exception {
    LexerGrammar lg = new LexerGrammar(
      "lexer grammar L;\n" +
      "A : 'a' ;\n" +
      "B : 'b' ;\n" +
      "C : 'c' ;\n" +
      "D : 'd' ;\n");
    Grammar g = new Grammar(
      "parser grammar T;\n"+
      "a : (A B | A B | C) D ;");
    checkMatchedAlt(lg, g, "abd", 1);
    checkMatchedAlt(lg, g, "abdc", 1);
    checkMatchedAlt(lg, g, "cd", 3);
  }

  @Test public void testAmbigAltChooseFirst2() throws Exception {
    LexerGrammar lg = new LexerGrammar(
      "lexer grammar L;\n" +
      "A : 'a' ;\n" +
      "B : 'b' ;\n" +
      "C : 'c' ;\n" +
      "D : 'd' ;\n");
    Grammar g = new Grammar(
      "parser grammar T;\n"+
      "a : A B | A B | A B C ;");

    checkMatchedAlt(lg, g, "ab", 1);
    checkMatchedAlt(lg, g, "abc", 3);

    checkMatchedAlt(lg, g, "abd", 1);
    checkMatchedAlt(lg, g, "abcd", 3);
  }

  @Test(expected = NoViableAltException.class)
  public void testAmbigAltChooseFirst2WithEOF() throws Exception {
    LexerGrammar lg = new LexerGrammar(
      "lexer grammar L;\n" +
      "A : 'a' ;\n" +
      "B : 'b' ;\n" +
      "C : 'c' ;\n" +
      "D : 'd' ;\n");
    Grammar g = new Grammar(
      "parser grammar T;\n"+
      "a : (A B | A B | A B C) EOF;");

    checkMatchedAlt(lg, g, "ab", 1);
    checkMatchedAlt(lg, g, "abc", 3);

    try {
      checkMatchedAlt(lg, g, "abd", 1);
    }
    catch (NoViableAltException re) {
      assertEquals(2, re.getOffendingToken().getTokenIndex());
      assertEquals(4, re.getOffendingToken().getType());
      throw re;
    }
  }

  @Test public void testSimpleLoop() throws Exception {
    LexerGrammar lg = new LexerGrammar(
      "lexer grammar L;\n" +
      "A : 'a' ;\n" +
      "B : 'b' ;\n" +
      "C : 'c' ;\n" +
      "D : 'd' ;\n");
    Grammar g = new Grammar(
      "parser grammar T;\n"+
      "a : A+ B ;");
    checkMatchedAlt(lg, g, "ab", 1);
    checkMatchedAlt(lg, g, "aab", 1);
    checkMatchedAlt(lg, g, "aaaaaab", 1);
    checkMatchedAlt(lg, g, "aabd", 1);
  }

  @Test public void testCommonLeftPrefix() throws Exception {
    LexerGrammar lg = new LexerGrammar(
      "lexer grammar L;\n" +
      "A : 'a' ;\n" +
      "B : 'b' ;\n" +
      "C : 'c' ;\n");
    Grammar g = new Grammar(
      "parser grammar T;\n"+
      "a : A B | A C ;");
    checkMatchedAlt(lg, g, "ab", 1);
    checkMatchedAlt(lg, g, "ac", 2);
  }

  @Test public void testArbitraryLeftPrefix() throws Exception {
    LexerGrammar lg = new LexerGrammar(
      "lexer grammar L;\n" +
      "A : 'a' ;\n" +
      "B : 'b' ;\n" +
      "C : 'c' ;\n");
    Grammar g = new Grammar(
      "parser grammar T;\n"+
      "a : A+ B | A+ C ;");
    checkMatchedAlt(lg, g, "aac", 2);
  }

  @Test public void testRecursiveLeftPrefix() throws Exception {
    LexerGrammar lg = new LexerGrammar(
      "lexer grammar L;\n" +
      "A : 'a' ;\n" +
      "B : 'b' ;\n" +
      "C : 'c' ;\n" +
      "LP : '(' ;\n" +
      "RP : ')' ;\n" +
      "INT : '0'..'9'+ ;\n"
    );
    Grammar g = new Grammar(
      "parser grammar T;\n"+
      "tokens {A,B,C,LP,RP,INT}\n" +
      "a : e B | e C ;\n" +
      "e : LP e RP\n" +
      "  | INT\n" +
      "  ;");
    checkMatchedAlt(lg, g, "34b", 1);
    checkMatchedAlt(lg, g, "34c", 2);
    checkMatchedAlt(lg, g, "(34)b", 1);
    checkMatchedAlt(lg, g, "(34)c", 2);
    checkMatchedAlt(lg, g, "((34))b", 1);
    checkMatchedAlt(lg, g, "((34))c", 2);
  }

  public void checkMatchedAlt(LexerGrammar lg, final Grammar g,
                String inputString,
                int expected)
  {
    ATN lexatn = createATN(lg, true);
    LexerATNSimulator lexInterp = new LexerATNSimulator(lexatn,new DFA[] { new DFA(lexatn.modeToStartState.get(Lexer.DEFAULT_MODE)) },null);
    IntegerList types = getTokenTypesViaATN(inputString, lexInterp);
    System.out.println(types);

    g.importVocab(lg);

    ParserATNFactory f = new ParserATNFactory(g);
    ATN atn = f.createATN();

    IntTokenStream input = new IntTokenStream(types);
    System.out.println("input="+input.types);
    ParserInterpreterForTesting interp = new ParserInterpreterForTesting(g, input);
    ATNState startState = atn.ruleToStartState[g.getRule("a").index];
    if ( startState.transition(0).target instanceof BlockStartState ) {
      startState = startState.transition(0).target;
    }

    DOTGenerator dot = new DOTGenerator(g);
    System.out.println(dot.getDOT(atn.ruleToStartState[g.getRule("a").index]));
    Rule r = g.getRule("e");
    if ( r!=null ) System.out.println(dot.getDOT(atn.ruleToStartState[r.index]));

    int result = interp.matchATN(input, startState);
    assertEquals(expected, result);
  }
}
TOP

Related Classes of org.antlr.v4.test.TestATNInterpreter

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.