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