📄 parser.cup
字号:
/*
// $Id: //open/mondrian/src/main/mondrian/olap/Parser.cup#19 $
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// (C) Copyright 1999-2005 Kana Software, Inc. and others.
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
//
// jhyde, 20 January, 1999
//
// Grammar condensed from OLE DB reference
// (http://www.microsoft.com/data/reference/oledb2.htm) by jhyde on 990120.
*/
import java_cup.runtime.*;
import java.util.ArrayList;
import mondrian.resource.MondrianResource;
// Preliminaries to set up and use the scanner.
// action code {: ... :};
parser code {:
// Generated from $Id: //open/mondrian/src/main/mondrian/olap/Parser.cup#19 $
private Scanner scanner;
private String queryString;
private Connection mdxConnection;
private FunTable funTable;
/**
* Parses a string to create a {@link Query}.
* Called only by {@link ConnectionBase#parseQuery}.
*/
Query parseInternal(
Connection mdxConnection,
String queryString,
boolean debug,
FunTable funTable)
{
Symbol parse_tree = null;
this.scanner = new StringScanner(queryString, debug);
this.mdxConnection = mdxConnection;
this.queryString = queryString;
this.funTable = funTable;
try {
if (debug) {
parse_tree = debug_parse();
} else {
parse_tree = parse();
}
return (Query) parse_tree.value;
} catch (Exception e) {
// "Error while parsing MDX statement '%1'"
throw MondrianResource.instance().WhileParsingMdx.ex(queryString, e);
} finally {
this.scanner = null;
this.mdxConnection = null;
this.queryString = null;
this.funTable = null;
}
}
/**
* Parses a string to create an {@link Exp}.
* Called only by {@link ConnectionBase#parseExpression}.
*/
Exp parseExpression(
Connection mdxConnection,
String queryString,
boolean debug,
FunTable funTable)
{
Symbol parse_tree = null;
this.scanner = new PrefixScanner(
debug,
new StringScanner(queryString, debug),
new int[] {ParserSym._VALUE_EXPRESSION});
this.mdxConnection = mdxConnection;
this.queryString = queryString;
this.funTable = funTable;
try {
if (debug) {
parse_tree = debug_parse();
} else {
parse_tree = parse();
}
return (Exp) parse_tree.value;
} catch (Exception e) {
// "Syntax error while parsing MDX expression '%1'"
throw MondrianResource.instance().WhileParsingMdxExpression.ex(queryString, e);
} finally {
this.scanner = null;
this.mdxConnection = null;
this.queryString = null;
this.funTable = null;
}
}
/**
* Scanner which returns a list of pre-programmed tokens, then switches
* to a parent scanner.
*/
private static class PrefixScanner extends Scanner {
private final Scanner parent;
private final int tokens[];
private int i;
PrefixScanner(boolean debug, Scanner parent, int[] tokens) {
super(debug);
this.parent = parent;
this.tokens = tokens;
}
public void init() throws java.io.IOException {
i = 0;
parent.init();
}
public Symbol next_token() throws java.io.IOException {
if (i < tokens.length) {
return new Symbol(tokens[i++], 0, 0, null);
}
return parent.next_token();
}
void getLocation(Symbol symbol, int[] loc) {
parent.getLocation(symbol, loc);
}
}
/** override this function to make your kind of query */
protected Query makeQuery(
Formula[] formulae, QueryAxis[] axes,
String cube, Exp slicer, QueryPart[] cellProps)
{
return new Query(
mdxConnection, formulae, axes, cube, slicer, cellProps);
}
// Override lr_parser methods for NLS. With this error handling scheme,
// all errors are fatal.
public void report_fatal_error(
String message,
Object info)
throws java.lang.Exception
{
done_parsing();
try {
report_error(message, info);
} catch (Throwable e) {
// "MDX parser cannot recover from previous error(s)"
throw MondrianResource.instance().MdxFatalError.ex(e);
}
}
// override lr_parser method
public void report_error(String message, Object info)
{
// "Error: %1"
throw MondrianResource.instance().MdxError.ex(message);
}
// override lr_parser method
public void syntax_error(Symbol cur_token)
{
String s = cur_token.value.toString();
if (cur_token.left != -1) {
int loc[] = new int[2];
scanner.getLocation(cur_token, loc);
// "Syntax error at line %2, column %3, token '%1'"
throw MondrianResource.instance().MdxSyntaxErrorAt.ex(
s, Integer.toString(loc[0] + 1), Integer.toString(loc[1] + 1));
} else {
// "Syntax error at token '%1'"
throw MondrianResource.instance().MdxSyntaxError.ex(s);
}
}
public void unrecovered_syntax_error(Symbol cur_token)
throws java.lang.Exception
{
// "Couldn't repair and continue parse"
String sFatalSyntaxError = MondrianResource.instance().MdxFatalSyntaxError.str();
report_fatal_error(sFatalSyntaxError, cur_token);
}
/**
* Returns whether the given identifier can possibly the name of an operator
* with property syntax.
*
* <p>For example, <code>isFunCall("ORDINAL")</code>
* returns true because there is a "<Level>.Ordinal" property.</p>
*/
protected boolean isFunCall(String s) {
return funTable.isProperty(s);
}
:};
init with {:
scanner.init();
:};
scan with {:
return scanner.next_token();
:};
// Terminals (tokens returned by the scanner).
// a. Keywords.
terminal
AND,
AS,
AXIS,
CASE,
CELL,
DIMENSION,
ELSE,
EMPTY,
END,
FROM,
IS,
MEMBER,
NON,
NOT,
NULL,
ON,
OR,
PROPERTIES,
QUOTE,
SELECT,
SET,
THEN,
WHEN,
WHERE,
XOR,
WITH,
_VALUE_EXPRESSION;
// b. Symbols
terminal
ASTERISK, // *
COLON, // :
COMMA, // ,
CONCAT, // ||
DOT, // .
EQ, // =
GE, // >=
GT, // >
LBRACE, // {
LE, // <=
LPAREN, // (
LT, // <
MINUS, // -
NE, // <>
PLUS, // +
RBRACE, // }
RPAREN, // )
SOLIDUS; // /
// c. Typed terminals
terminal Double NUMBER;
terminal String ID;
terminal String QUOTED_ID;
terminal String AMP_QUOTED_ID;
terminal String STRING;
terminal String UNKNOWN; // a token the lexer doesn't like!
// Non terminals
non terminal QueryAxis
axis_specification;
non terminal Exp
case_expression,
else_clause_opt,
expression,
factor,
slicer_specification,
term,
term2,
term3,
term4,
term5,
value_expression,
value_expression_opt,
value_expression_primary,
where_clause_opt;
non terminal QueryPart
select_statement,
statement;
non terminal Id
compound_id,
cube_name,
cube_specification,
member_name,
set_name;
non terminal String
axis_name,
comp_op,
identifier,
quoted_identifier,
unquoted_identifier,
amp_quoted_identifier,
keyword;
non terminal Formula
member_specification,
set_specification,
single_formula_specification;
non terminal MemberProperty
member_property_definition;
non terminal
cell_opt,
cell_property,
cell_property_list,
dim_props,
dim_props_opt,
dimension_opt,
mandatory_cell_property,
optional_cell_property,
property,
property_list,
provider_specific_cell_property,
unsigned_integer;
non terminal Boolean
non_empty_opt;
non terminal ArrayList
axis_specification_list,
axis_specification_list_opt,
cell_props,
cell_props_opt,
comma_member_property_def_list_opt,
exp_list,
exp_list_opt,
formula_specification,
member_property_def_list,
when_list,
with_formula_specification_opt;
non terminal Exp[]
when_clause;
non terminal Double
axis_number;
// Start symbol
start with statement;
// ----------------------------------------------------------------------------
// Elements
//
//
// <identifier> ::= <regular_identifier> | <delimited_identifier>
quoted_identifier ::=
QUOTED_ID
;
amp_quoted_identifier ::=
AMP_QUOTED_ID
;
unquoted_identifier ::=
ID
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -