// ---- ExpressionParser.java -----------------
//header.txt
package org.intellij.grammar.expression;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiBuilder.Marker;
import static org.intellij.grammar.expression.ExpressionTypes.*;
import static org.intellij.grammar.parser.GeneratedParserUtilBase.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.lang.ASTNode;
import com.intellij.psi.tree.TokenSet;
import com.intellij.lang.PsiParser;
import com.intellij.lang.LightPsiParser;
@SuppressWarnings({"SimplifiableIfStatement", "UnusedAssignment"})
public class ExpressionParser implements PsiParser, LightPsiParser {
public ASTNode parse(IElementType root_, PsiBuilder builder_) {
parseLight(root_, builder_);
return builder_.getTreeBuilt();
}
public void parseLight(IElementType root_, PsiBuilder builder_) {
boolean result_;
builder_ = adapt_builder_(root_, builder_, this, EXTENDS_SETS_);
Marker marker_ = enter_section_(builder_, 0, _COLLAPSE_, null);
if (root_ == ARG_LIST) {
result_ = arg_list(builder_, 0);
}
else if (root_ == EXPR) {
result_ = expr(builder_, 0, -1);
}
else if (root_ == IDENTIFIER) {
result_ = identifier(builder_, 0);
}
else {
result_ = parse_root_(root_, builder_, 0);
}
exit_section_(builder_, 0, marker_, root_, result_, true, TRUE_CONDITION);
}
protected boolean parse_root_(IElementType root_, PsiBuilder builder_, int level_) {
return root(builder_, level_ + 1);
}
public static final TokenSet[] EXTENDS_SETS_ = new TokenSet[] {
create_token_set_(ASSIGN_EXPR, BETWEEN_EXPR, CALL_EXPR, CONDITIONAL_EXPR,
DIV_EXPR, ELVIS_EXPR, EXPR, EXP_EXPR,
FACTORIAL_EXPR, IS_NOT_EXPR, LITERAL_EXPR, MINUS_EXPR,
MUL_EXPR, PAREN_EXPR, PLUS_EXPR, REF_EXPR,
SPECIAL_EXPR, UNARY_MIN_EXPR, UNARY_NOT_EXPR, UNARY_PLUS_EXPR,
XOR_EXPR),
};
/* ********************************************************** */
// '(' [ !')' expr (',' expr) * ] ')'
public static boolean arg_list(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "arg_list")) return false;
boolean result_, pinned_;
Marker marker_ = enter_section_(builder_, level_, _NONE_, ARG_LIST, "<arg list>");
result_ = consumeToken(builder_, "(");
pinned_ = result_; // pin = 1
result_ = result_ && report_error_(builder_, arg_list_1(builder_, level_ + 1));
result_ = pinned_ && consumeToken(builder_, ")") && result_;
exit_section_(builder_, level_, marker_, result_, pinned_, null);
return result_ || pinned_;
}
// [ !')' expr (',' expr) * ]
private static boolean arg_list_1(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "arg_list_1")) return false;
arg_list_1_0(builder_, level_ + 1);
return true;
}
// !')' expr (',' expr) *
private static boolean arg_list_1_0(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "arg_list_1_0")) return false;
boolean result_, pinned_;
Marker marker_ = enter_section_(builder_, level_, _NONE_);
result_ = arg_list_1_0_0(builder_, level_ + 1);
pinned_ = result_; // pin = 1
result_ = result_ && report_error_(builder_, expr(builder_, level_ + 1, -1));
result_ = pinned_ && arg_list_1_0_2(builder_, level_ + 1) && result_;
exit_section_(builder_, level_, marker_, result_, pinned_, null);
return result_ || pinned_;
}
// !')'
private static boolean arg_list_1_0_0(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "arg_list_1_0_0")) return false;
boolean result_;
Marker marker_ = enter_section_(builder_, level_, _NOT_);
result_ = !consumeToken(builder_, ")");
exit_section_(builder_, level_, marker_, result_, false, null);
return result_;
}
// (',' expr) *
private static boolean arg_list_1_0_2(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "arg_list_1_0_2")) return false;
int pos_ = current_position_(builder_);
while (true) {
if (!arg_list_1_0_2_0(builder_, level_ + 1)) break;
if (!empty_element_parsed_guard_(builder_, "arg_list_1_0_2", pos_)) break;
pos_ = current_position_(builder_);
}
return true;
}
// ',' expr
private static boolean arg_list_1_0_2_0(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "arg_list_1_0_2_0")) return false;
boolean result_, pinned_;
Marker marker_ = enter_section_(builder_, level_, _NONE_);
result_ = consumeToken(builder_, ",");
pinned_ = result_; // pin = 1
result_ = result_ && expr(builder_, level_ + 1, -1);
exit_section_(builder_, level_, marker_, result_, pinned_, null);
return result_ || pinned_;
}
/* ********************************************************** */
// expr ';'?
static boolean element(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "element")) return false;
boolean result_;
Marker marker_ = enter_section_(builder_, level_, _NONE_);
result_ = expr(builder_, level_ + 1, -1);
result_ = result_ && element_1(builder_, level_ + 1);
exit_section_(builder_, level_, marker_, result_, false, element_recover_parser_);
return result_;
}
// ';'?
private static boolean element_1(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "element_1")) return false;
consumeToken(builder_, ";");
return true;
}
/* ********************************************************** */
// !('(' | '+' | '-' | '!' | 'multiply' | id | number)
static boolean element_recover(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "element_recover")) return false;
boolean result_;
Marker marker_ = enter_section_(builder_, level_, _NOT_);
result_ = !element_recover_0(builder_, level_ + 1);
exit_section_(builder_, level_, marker_, result_, false, null);
return result_;
}
// '(' | '+' | '-' | '!' | 'multiply' | id | number
private static boolean element_recover_0(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "element_recover_0")) return false;
boolean result_;
Marker marker_ = enter_section_(builder_);
result_ = consumeToken(builder_, "(");
if (!result_) result_ = consumeToken(builder_, "+");
if (!result_) result_ = consumeToken(builder_, "-");
if (!result_) result_ = consumeToken(builder_, "!");
if (!result_) result_ = consumeToken(builder_, "multiply");
if (!result_) result_ = consumeToken(builder_, ID);
if (!result_) result_ = consumeToken(builder_, NUMBER);
exit_section_(builder_, marker_, null, result_);
return result_;
}
/* ********************************************************** */
// id
public static boolean identifier(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "identifier")) return false;
if (!nextTokenIs(builder_, ID)) return false;
boolean result_;
Marker marker_ = enter_section_(builder_);
result_ = consumeToken(builder_, ID);
exit_section_(builder_, marker_, IDENTIFIER, result_);
return result_;
}
/* ********************************************************** */
// element *
static boolean root(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "root")) return false;
int pos_ = current_position_(builder_);
while (true) {
if (!element(builder_, level_ + 1)) break;
if (!empty_element_parsed_guard_(builder_, "root", pos_)) break;
pos_ = current_position_(builder_);
}
return true;
}
/* ********************************************************** */
// Expression root: expr
// Operator priority table:
// 0: BINARY(assign_expr)
// 1: BINARY(elvis_expr) BINARY(conditional_expr)
// 2: BINARY(plus_expr) BINARY(minus_expr)
// 3: BINARY(xor_expr) BINARY(between_expr) BINARY(is_not_expr)
// 4: BINARY(mul_expr) BINARY(div_expr)
// 5: PREFIX(unary_plus_expr) PREFIX(unary_min_expr) PREFIX(unary_not_expr)
// 6: N_ARY(exp_expr)
// 7: POSTFIX(factorial_expr)
// 8: POSTFIX(call_expr)
// 9: POSTFIX(qualification_expr)
// 10: ATOM(special_expr) ATOM(simple_ref_expr) ATOM(literal_expr) PREFIX(paren_expr)
public static boolean expr(PsiBuilder builder_, int level_, int priority_) {
if (!recursion_guard_(builder_, level_, "expr")) return false;
addVariant(builder_, "<expr>");
boolean result_, pinned_;
Marker marker_ = enter_section_(builder_, level_, _NONE_, "<expr>");
result_ = unary_plus_expr(builder_, level_ + 1);
if (!result_) result_ = unary_min_expr(builder_, level_ + 1);
if (!result_) result_ = unary_not_expr(builder_, level_ + 1);
if (!result_) result_ = special_expr(builder_, level_ + 1);
if (!result_) result_ = simple_ref_expr(builder_, level_ + 1);
if (!result_) result_ = literal_expr(builder_, level_ + 1);
if (!result_) result_ = paren_expr(builder_, level_ + 1);
pinned_ = result_;
result_ = result_ && expr_0(builder_, level_ + 1, priority_);
exit_section_(builder_, level_, marker_, null, result_, pinned_, null);
return result_ || pinned_;
}
public static boolean expr_0(PsiBuilder builder_, int level_, int priority_) {
if (!recursion_guard_(builder_, level_, "expr_0")) return false;
boolean result_ = true;
while (true) {
Marker marker_ = enter_section_(builder_, level_, _LEFT_, null);
if (priority_ < 0 && consumeTokenSmart(builder_, "=")) {
result_ = expr(builder_, level_, -1);
exit_section_(builder_, level_, marker_, ASSIGN_EXPR, result_, true, null);
}
else if (priority_ < 1 && consumeTokenSmart(builder_, "?")) {
result_ = report_error_(builder_, expr(builder_, level_, 1));
result_ = elvis_expr_1(builder_, level_ + 1) && result_;
exit_section_(builder_, level_, marker_, ELVIS_EXPR, result_, true, null);
}
else if (priority_ < 1 && conditional_expr_0(builder_, level_ + 1)) {
result_ = expr(builder_, level_, 1);
exit_section_(builder_, level_, marker_, CONDITIONAL_EXPR, result_, true, null);
}
else if (priority_ < 2 && consumeTokenSmart(builder_, "+")) {
result_ = expr(builder_, level_, 2);
exit_section_(builder_, level_, marker_, PLUS_EXPR, result_, true, null);
}
else if (priority_ < 2 && consumeTokenSmart(builder_, "-")) {
result_ = expr(builder_, level_, 2);
exit_section_(builder_, level_, marker_, MINUS_EXPR, result_, true, null);
}
else if (priority_ < 3 && consumeTokenSmart(builder_, "^")) {
result_ = expr(builder_, level_, 3);
exit_section_(builder_, level_, marker_, XOR_EXPR, result_, true, null);
}
else if (priority_ < 3 && consumeTokenSmart(builder_, BETWEEN)) {
result_ = report_error_(builder_, expr(builder_, level_, 3));
result_ = between_expr_1(builder_, level_ + 1) && result_;
exit_section_(builder_, level_, marker_, BETWEEN_EXPR, result_, true, null);
}
else if (priority_ < 3 && parseTokensSmart(builder_, 0, IS, NOT)) {
result_ = expr(builder_, level_, 3);
exit_section_(builder_, level_, marker_, IS_NOT_EXPR, result_, true, null);
}
else if (priority_ < 4 && consumeTokenSmart(builder_, "*")) {
result_ = expr(builder_, level_, 4);
exit_section_(builder_, level_, marker_, MUL_EXPR, result_, true, null);
}
else if (priority_ < 4 && consumeTokenSmart(builder_, "/")) {
result_ = expr(builder_, level_, 4);
exit_section_(builder_, level_, marker_, DIV_EXPR, result_, true, null);
}
else if (priority_ < 7 && consumeTokenSmart(builder_, "!")) {
result_ = true;
exit_section_(builder_, level_, marker_, FACTORIAL_EXPR, result_, true, null);
}
else if (priority_ < 6 && consumeTokenSmart(builder_, "**")) {
while (true) {
result_ = report_error_(builder_, expr(builder_, level_, 6));
if (!consumeTokenSmart(builder_, "**")) break;
}
exit_section_(builder_, level_, marker_, EXP_EXPR, result_, true, null);
}
else if (priority_ < 8 && leftMarkerIs(builder_, REF_EXPR) && arg_list(builder_, level_ + 1)) {
result_ = true;
exit_section_(builder_, level_, marker_, CALL_EXPR, result_, true, null);
}
else if (priority_ < 9 && qualification_expr_0(builder_, level_ + 1)) {
result_ = true;
exit_section_(builder_, level_, marker_, REF_EXPR, result_, true, null);
}
else {
exit_section_(builder_, level_, marker_, null, false, false, null);
break;
}
}
return result_;
}
// ':' expr
private static boolean elvis_expr_1(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "elvis_expr_1")) return false;
boolean result_;
Marker marker_ = enter_section_(builder_);
result_ = consumeToken(builder_, ":");
result_ = result_ && expr(builder_, level_ + 1, -1);
exit_section_(builder_, marker_, null, result_);
return result_;
}
// '<' | '>' | '<=' | '>=' | '==' | '!='
private static boolean conditional_expr_0(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "conditional_expr_0")) return false;
boolean result_;
Marker marker_ = enter_section_(builder_);
result_ = consumeTokenSmart(builder_, "<");
if (!result_) result_ = consumeTokenSmart(builder_, ">");
if (!result_) result_ = consumeTokenSmart(builder_, "<=");
if (!result_) result_ = consumeTokenSmart(builder_, ">=");
if (!result_) result_ = consumeTokenSmart(builder_, "==");
if (!result_) result_ = consumeTokenSmart(builder_, "!=");
exit_section_(builder_, marker_, null, result_);
return result_;
}
public static boolean unary_plus_expr(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "unary_plus_expr")) return false;
boolean result_, pinned_;
Marker marker_ = enter_section_(builder_, level_, _NONE_, null);
result_ = consumeTokenSmart(builder_, "+");
pinned_ = result_;
result_ = pinned_ && expr(builder_, level_, 5);
exit_section_(builder_, level_, marker_, UNARY_PLUS_EXPR, result_, pinned_, null);
return result_ || pinned_;
}
public static boolean unary_min_expr(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "unary_min_expr")) return false;
boolean result_, pinned_;
Marker marker_ = enter_section_(builder_, level_, _NONE_, null);
result_ = consumeTokenSmart(builder_, "-");
pinned_ = result_;
result_ = pinned_ && expr(builder_, level_, 5);
exit_section_(builder_, level_, marker_, UNARY_MIN_EXPR, result_, pinned_, null);
return result_ || pinned_;
}
// AND add_group
private static boolean between_expr_1(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "between_expr_1")) return false;
boolean result_;
Marker marker_ = enter_section_(builder_);
result_ = consumeToken(builder_, AND);
result_ = result_ && expr(builder_, level_ + 1, -2);
exit_section_(builder_, marker_, null, result_);
return result_;
}
public static boolean unary_not_expr(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "unary_not_expr")) return false;
boolean result_, pinned_;
Marker marker_ = enter_section_(builder_, level_, _NONE_, null);
result_ = consumeTokenSmart(builder_, "!");
pinned_ = result_;
result_ = pinned_ && expr(builder_, level_, 5);
exit_section_(builder_, level_, marker_, UNARY_NOT_EXPR, result_, pinned_, null);
return result_ || pinned_;
}
// '.' identifier
private static boolean qualification_expr_0(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "qualification_expr_0")) return false;
boolean result_;
Marker marker_ = enter_section_(builder_);
result_ = consumeTokenSmart(builder_, ".");
result_ = result_ && identifier(builder_, level_ + 1);
exit_section_(builder_, marker_, null, result_);
return result_;
}
// 'multiply' '(' simple_ref_expr ',' mul_expr ')'
public static boolean special_expr(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "special_expr")) return false;
boolean result_, pinned_;
Marker marker_ = enter_section_(builder_, level_, _NONE_, SPECIAL_EXPR, "<special expr>");
result_ = consumeTokenSmart(builder_, "multiply");
result_ = result_ && consumeToken(builder_, "(");
pinned_ = result_; // pin = 2
result_ = result_ && report_error_(builder_, simple_ref_expr(builder_, level_ + 1));
result_ = pinned_ && report_error_(builder_, consumeToken(builder_, ",")) && result_;
result_ = pinned_ && report_error_(builder_, expr(builder_, level_ + 1, 3)) && result_;
result_ = pinned_ && consumeToken(builder_, ")") && result_;
exit_section_(builder_, level_, marker_, result_, pinned_, null);
return result_ || pinned_;
}
// identifier
public static boolean simple_ref_expr(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "simple_ref_expr")) return false;
if (!nextTokenIsSmart(builder_, ID)) return false;
boolean result_;
Marker marker_ = enter_section_(builder_);
result_ = identifier(builder_, level_ + 1);
exit_section_(builder_, marker_, REF_EXPR, result_);
return result_;
}
// number
public static boolean literal_expr(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "literal_expr")) return false;
if (!nextTokenIsSmart(builder_, NUMBER)) return false;
boolean result_;
Marker marker_ = enter_section_(builder_);
result_ = consumeTokenSmart(builder_, NUMBER);
exit_section_(builder_, marker_, LITERAL_EXPR, result_);
return result_;
}
public static boolean paren_expr(PsiBuilder builder_, int level_) {
if (!recursion_guard_(builder_, level_, "paren_expr")) return false;
boolean result_, pinned_;
Marker marker_ = enter_section_(builder_, level_, _NONE_, null);
result_ = consumeTokenSmart(builder_, "(");
pinned_ = result_;
result_ = pinned_ && expr(builder_, level_, -1);
result_ = pinned_ && report_error_(builder_, consumeToken(builder_, ")")) && result_;
exit_section_(builder_, level_, marker_, PAREN_EXPR, result_, pinned_, null);
return result_ || pinned_;
}
final static Parser element_recover_parser_ = new Parser() {
public boolean parse(PsiBuilder builder_, int level_) {
return element_recover(builder_, level_ + 1);
}
};
}