001/* 002// This software is subject to the terms of the Eclipse Public License v1.0 003// Agreement, available at the following URL: 004// http://www.eclipse.org/legal/epl-v10.html. 005// You must accept the terms of that agreement to use this software. 006// 007// Copyright (C) 2010-2011 Pentaho 008// All Rights Reserved. 009*/ 010package mondrian.parser; 011 012import mondrian.olap.*; 013import mondrian.server.Statement; 014 015/** 016 * Default implementation of {@link MdxParserValidator}, using the 017 * <a href="http://java.net/projects/javacc/">JavaCC</a> parser generator. 018 * 019 * @author jhyde 020 */ 021public class JavaccParserValidatorImpl implements MdxParserValidator { 022 private final QueryPartFactory factory; 023 024 /** 025 * Creates a JavaccParserValidatorImpl. 026 */ 027 public JavaccParserValidatorImpl() { 028 this(new Parser.FactoryImpl()); 029 } 030 031 /** 032 * Creates a JavaccParserValidatorImpl with an explicit factory for parse 033 * tree nodes. 034 * 035 * @param factory Factory for parse tree nodes 036 */ 037 public JavaccParserValidatorImpl(QueryPartFactory factory) { 038 this.factory = factory; 039 } 040 041 public QueryPart parseInternal( 042 Statement statement, 043 String queryString, 044 boolean debug, 045 FunTable funTable, 046 boolean strictValidation) 047 { 048 final MdxParserImpl mdxParser = 049 new MdxParserImpl( 050 factory, 051 statement, 052 queryString, 053 debug, 054 funTable, 055 strictValidation); 056 try { 057 return mdxParser.statementEof(); 058 } catch (ParseException e) { 059 throw convertException(queryString, e); 060 } 061 } 062 063 public Exp parseExpression( 064 Statement statement, 065 String queryString, 066 boolean debug, 067 FunTable funTable) 068 { 069 final MdxParserImpl mdxParser = 070 new MdxParserImpl( 071 factory, 072 statement, 073 queryString, 074 debug, 075 funTable, 076 false); 077 try { 078 return mdxParser.expressionEof(); 079 } catch (ParseException e) { 080 throw convertException(queryString, e); 081 } 082 } 083 084 /** 085 * Converts the exception so that it looks like the exception produced by 086 * JavaCUP. (Not that that format is ideal, but it minimizes test output 087 * changes during the transition from JavaCUP to JavaCC.) 088 * 089 * @param queryString MDX query string 090 * @param pe JavaCC parse exception 091 * @return Wrapped exception 092 */ 093 private RuntimeException convertException( 094 String queryString, 095 ParseException pe) 096 { 097 Exception e; 098 if (pe.getMessage().startsWith("Encountered ")) { 099 e = new MondrianException( 100 "Syntax error at line " 101 + pe.currentToken.next.beginLine 102 + ", column " 103 + pe.currentToken.next.beginColumn 104 + ", token '" 105 + pe.currentToken.next.image 106 + "'"); 107 } else { 108 e = pe; 109 } 110 return Util.newError(e, "While parsing " + queryString); 111 } 112} 113 114// End JavaccParserValidatorImpl.java