This project has retired. For details please refer to its Attic page.
AbstractParserTest xref

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.chemistry.opencmis.server.support.query;
20  
21  import static org.junit.Assert.fail;
22  
23  import java.lang.reflect.Constructor;
24  import java.lang.reflect.Method;
25  
26  import org.antlr.runtime.ANTLRStringStream;
27  import org.antlr.runtime.BaseRecognizer;
28  import org.antlr.runtime.CharStream;
29  import org.antlr.runtime.CommonTokenStream;
30  import org.antlr.runtime.Lexer;
31  import org.antlr.runtime.TokenStream;
32  import org.antlr.runtime.tree.CommonTree;
33  import org.antlr.stringtemplate.StringTemplate;
34  import org.apache.commons.logging.Log;
35  import org.apache.commons.logging.LogFactory;
36  
37  /**
38   *  This class is clone of org.antlr.gunit.gUnitBase class adapted to Java style
39   *  Because the original class can't deal with composite grammar this is a replacement
40   *  working around this antlr bug.
41   *
42   */
43  public class AbstractParserTest{
44  
45      private static final Log log = LogFactory.getLog(AbstractParserTest.class);
46  
47      protected String superGrammarName;
48      Class<?> lexer;
49      Class<?> parser;
50      protected String treeParserPath;
51  
52      protected void setUp(Class<?> lexerClass, Class<?> parserClass, String baseGrammar)  {
53          lexer = lexerClass;
54          parser = parserClass;
55          this.superGrammarName = baseGrammar;
56      }
57  
58      protected void tearDown() {
59      }
60  
61      protected void testLexerOk(String rule, String statement) {
62          // test input: "a"
63        try {
64          Object retval = execLexer(rule, statement, false);
65          log.debug("testing rule " + rule + " parsed to: " + retval);
66        } catch (Exception e) {
67            fail("testing rule " + rule + ": " + e.toString());
68        }
69      }
70  
71      protected void testLexerFail(String rule, String statement) {
72          // test input: "a"
73        try {
74          Object retval = execLexer(rule, statement, false);
75          fail("testing rule should fail " + rule);
76        } catch (Exception e) {
77          log.debug("testing rule " + rule + " parsed with exception: " + e);
78        }
79      }
80  
81      protected void testParserOk(String rule, String statement) {
82        try {
83            Object retval = execParser(rule, statement, false);
84            log.debug("testing rule " + rule + " parsed to: " + retval);
85        } catch (Exception e) {
86            fail("testing rule "+rule + " failed: " + e.toString());
87        }
88      }
89  
90      protected void testParserFail(String rule, String statement) {
91        try {
92            Object retval = execParser(rule, statement, false);
93            fail("testing rule should fail " + rule);
94        } catch (Exception e) {
95            log.debug("testing rule "+rule + " failed: " + e.toString());
96        }
97      }
98  
99      protected void testParser(String rule, String statement, String expectedResult) {
100       try {
101           Object actual = execParser(rule, statement, false);
102           log.debug("testing rule " + rule + " parsed to: " + actual);
103       } catch (Exception e) {
104         fail("testing rule " + rule + " failed: " + e);
105       }
106     }
107 
108 
109     // Invoke target lexer.rule
110     public String execLexer(String testRuleName, String testInput, boolean isFile) throws Exception {
111         String result = null;
112         CharStream input;
113         /** Set up ANTLR input stream based on input source, file or String */
114         input = new ANTLRStringStream(testInput);
115 
116         /** Use Reflection to create instances of lexer and parser */
117         Class<?>[] lexArgTypes = new Class[]{CharStream.class};                // assign type to lexer's args
118         Constructor<?> lexConstructor = lexer.getConstructor(lexArgTypes);
119         Object[] lexArgs = new Object[]{input};                             // assign value to lexer's args
120         Object lexObj = lexConstructor.newInstance(lexArgs);                // makes new instance of lexer
121 
122         Method ruleName = lexer.getMethod("m"+testRuleName, new Class[0]);
123 
124         /** Invoke lexer rule, and get the current index in CharStream */
125         ruleName.invoke(lexObj, new Object[0]);
126         Method ruleName2 = lexer.getMethod("getCharIndex", new Class[0]);
127         int currentIndex = (Integer) ruleName2.invoke(lexObj, new Object[0]);
128         if ( currentIndex!=input.size() ) {
129             throw new RuntimeException("extra text found, '"+input.substring(currentIndex, input.size()-1)+"'");
130 //            System.out.println("extra text found, '"+input.substring(currentIndex, input.size()-1)+"'");
131         }
132 
133         return result;
134     }
135 
136     // Invoke target parser.rule
137     public Object execParser(String testRuleName, String testInput, boolean isFile) throws Exception {
138         String result = null;
139         CharStream input;
140         /** Set up ANTLR input stream based on input source, file or String */
141         input = new ANTLRStringStream(testInput);
142 
143         /** Use Reflection to create instances of lexer and parser */
144         Class<?>[] lexArgTypes = new Class[]{CharStream.class};                // assign type to lexer's args
145         Constructor<?> lexConstructor = lexer.getConstructor(lexArgTypes);
146         Object[] lexArgs = new Object[]{input};                             // assign value to lexer's args
147         Object lexObj = lexConstructor.newInstance(lexArgs);                // makes new instance of lexer
148 
149         CommonTokenStream tokens = new CommonTokenStream((Lexer) lexObj);
150         Class<?>[] parArgTypes = new Class[]{TokenStream.class};               // assign type to parser's args
151         Constructor<?> parConstructor = parser.getConstructor(parArgTypes);
152         Object[] parArgs = new Object[]{tokens};                            // assign value to parser's args
153         Object parObj = parConstructor.newInstance(parArgs);                // makes new instance of parser
154 
155         Method ruleName = parser.getMethod(testRuleName);
156 
157         /** Invoke grammar rule, and store if there is a return value */
158         Object ruleReturn = ruleName.invoke(parObj);
159 
160         /** If rule has return value, determine if it contains an AST or a ST */
161         if ( ruleReturn!=null ) {
162             if ( ruleReturn.getClass().toString().indexOf(testRuleName+"_return")>0 ) {
163                 try {   // NullPointerException may happen here...
164                     String classPath = parser.getName();
165                     if (null != superGrammarName) {
166                         classPath += "_" + superGrammarName;
167                     }
168                     Class<?> _return = Class.forName(classPath+"$"+testRuleName+"_return");
169                     Method[] methods = _return.getDeclaredMethods();
170                     for(Method method : methods) {
171                         if ( method.getName().equals("getTree") ) {
172                             Method returnName = _return.getMethod("getTree");
173                             CommonTree tree = (CommonTree) returnName.invoke(ruleReturn);
174                             result = tree.toStringTree();
175                         }
176                         else if ( method.getName().equals("getTemplate") ) {
177                             Method returnName = _return.getMethod("getTemplate");
178                             StringTemplate st = (StringTemplate) returnName.invoke(ruleReturn);
179                             result = st.toString();
180                         }
181                     }
182                 }
183                 catch(Exception e) {
184                     throw(e);  // Note: If any exception occurs, the test is viewed as failed.
185                 }
186             }
187         }
188 
189 
190         /** Invalid input */
191         if ( tokens.index()!=tokens.size() ) {
192             throw new RuntimeException("Invalid input.");
193         }
194 
195         /** Check for syntax errors */
196         if (((BaseRecognizer)parObj).getNumberOfSyntaxErrors() > 0) {
197             throw new RuntimeException("Syntax error occured");
198         }
199         return result;
200     }
201 
202  }