Parser: raise corpus parse rate from 57% to 69%
Grammar gains: array types, directive flags, declaration-level directive modifiers, parameter markers, backticked declaration names, notes after a block-valued declaration, 'if cond then stmt', 'ifx c else v', '#module_parameters' two-group form, '(.*)' prefix dereference, and '#asm' bodies consumed opaquely (they are x86-64 assembly, not Jai). Return items no longer take a default value: allowing one made 'f: (K) -> u32 = null' swallow the enclosing parameter's default and read the rest of the parameter list as extra return values.
This commit is contained in:
@@ -39,14 +39,14 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
create_token_set_(ADD_EXPR, AND_EXPR, ARRAY_LITERAL_EXPR, ARRAY_TYPE_EXPR,
|
create_token_set_(ADD_EXPR, AND_EXPR, ARRAY_LITERAL_EXPR, ARRAY_TYPE_EXPR,
|
||||||
ASSIGN_EXPR, AUTO_CAST_EXPR, BACKTICK_EXPR, BIT_AND_EXPR,
|
ASSIGN_EXPR, AUTO_CAST_EXPR, BACKTICK_EXPR, BIT_AND_EXPR,
|
||||||
BIT_OR_EXPR, BIT_XOR_EXPR, BUILTIN_CALL_EXPR, CALL_EXPR,
|
BIT_OR_EXPR, BIT_XOR_EXPR, BUILTIN_CALL_EXPR, CALL_EXPR,
|
||||||
CAST_EXPR, DEREF_EXPR, DIRECTIVE_EXPR, ENUM_EXPR,
|
CAST_EXPR, DEREF_CAST_EXPR, DEREF_EXPR, DIRECTIVE_EXPR,
|
||||||
EQUALITY_EXPR, EXPR, IFX_EXPR, INDEX_EXPR,
|
ENUM_EXPR, EQUALITY_EXPR, EXPR, IFX_EXPR,
|
||||||
INLINE_EXPR, INTERFACE_EXPR, LAMBDA_EXPR, LITERAL_EXPR,
|
INDEX_EXPR, INLINE_EXPR, INTERFACE_EXPR, LAMBDA_EXPR,
|
||||||
MEMBER_EXPR, MUL_EXPR, OR_EXPR, PAREN_EXPR,
|
LITERAL_EXPR, MEMBER_EXPR, MUL_EXPR, OR_EXPR,
|
||||||
PREFIX_EXPR, PRIMARY_EXPR, PROC_LITERAL_EXPR, RANGE_EXPR,
|
PAREN_EXPR, PREFIX_EXPR, PRIMARY_EXPR, PROC_LITERAL_EXPR,
|
||||||
REF_EXPR, RELATIONAL_EXPR, SHIFT_EXPR, STRUCT_EXPR,
|
RANGE_EXPR, REF_EXPR, RELATIONAL_EXPR, SHIFT_EXPR,
|
||||||
STRUCT_LITERAL_EXPR, TYPED_ARRAY_LITERAL_EXPR, TYPED_STRUCT_LITERAL_EXPR, UNARY_DOT_EXPR,
|
STRUCT_EXPR, STRUCT_LITERAL_EXPR, TYPED_ARRAY_LITERAL_EXPR, TYPED_STRUCT_LITERAL_EXPR,
|
||||||
UNINITIALIZED_EXPR, UNION_EXPR),
|
UNARY_DOT_EXPR, UNINITIALIZED_EXPR, UNION_EXPR),
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
@@ -326,31 +326,49 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// <<dirPlain>> | 'using'
|
// procModifier | 'using'
|
||||||
static boolean declModifier_(PsiBuilder builder_, int level_) {
|
static boolean declModifier_(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "declModifier_")) return false;
|
if (!recursion_guard_(builder_, level_, "declModifier_")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
Marker marker_ = enter_section_(builder_);
|
result_ = procModifier(builder_, level_ + 1);
|
||||||
result_ = dirPlain(builder_, level_ + 1);
|
|
||||||
if (!result_) result_ = consumeToken(builder_, KW_USING);
|
if (!result_) result_ = consumeToken(builder_, KW_USING);
|
||||||
exit_section_(builder_, marker_, null, result_);
|
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// IDENT (',' IDENT)*
|
// ['`'] IDENT
|
||||||
public static boolean declNames(PsiBuilder builder_, int level_) {
|
public static boolean declName(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "declNames")) return false;
|
if (!recursion_guard_(builder_, level_, "declName")) return false;
|
||||||
if (!nextTokenIs(builder_, IDENT)) return false;
|
if (!nextTokenIs(builder_, "<decl name>", BACKTICK, IDENT)) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
Marker marker_ = enter_section_(builder_);
|
Marker marker_ = enter_section_(builder_, level_, _NONE_, DECL_NAME, "<decl name>");
|
||||||
result_ = consumeToken(builder_, IDENT);
|
result_ = declName_0(builder_, level_ + 1);
|
||||||
result_ = result_ && declNames_1(builder_, level_ + 1);
|
result_ = result_ && consumeToken(builder_, IDENT);
|
||||||
exit_section_(builder_, marker_, DECL_NAMES, result_);
|
exit_section_(builder_, level_, marker_, result_, false, null);
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// (',' IDENT)*
|
// ['`']
|
||||||
|
private static boolean declName_0(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "declName_0")) return false;
|
||||||
|
consumeToken(builder_, BACKTICK);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ********************************************************** */
|
||||||
|
// declName (',' declName)*
|
||||||
|
public static boolean declNames(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "declNames")) return false;
|
||||||
|
if (!nextTokenIs(builder_, "<decl names>", BACKTICK, IDENT)) return false;
|
||||||
|
boolean result_;
|
||||||
|
Marker marker_ = enter_section_(builder_, level_, _NONE_, DECL_NAMES, "<decl names>");
|
||||||
|
result_ = declName(builder_, level_ + 1);
|
||||||
|
result_ = result_ && declNames_1(builder_, level_ + 1);
|
||||||
|
exit_section_(builder_, level_, marker_, result_, false, null);
|
||||||
|
return result_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// (',' declName)*
|
||||||
private static boolean declNames_1(PsiBuilder builder_, int level_) {
|
private static boolean declNames_1(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "declNames_1")) return false;
|
if (!recursion_guard_(builder_, level_, "declNames_1")) return false;
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -361,18 +379,19 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ',' IDENT
|
// ',' declName
|
||||||
private static boolean declNames_1_0(PsiBuilder builder_, int level_) {
|
private static boolean declNames_1_0(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "declNames_1_0")) return false;
|
if (!recursion_guard_(builder_, level_, "declNames_1_0")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
Marker marker_ = enter_section_(builder_);
|
Marker marker_ = enter_section_(builder_);
|
||||||
result_ = consumeTokens(builder_, 0, COMMA, IDENT);
|
result_ = consumeToken(builder_, COMMA);
|
||||||
|
result_ = result_ && declName(builder_, level_ + 1);
|
||||||
exit_section_(builder_, marker_, null, result_);
|
exit_section_(builder_, marker_, null, result_);
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// ':' [<<exprNoAssign>>] [('=' | ':') initializer]
|
// ':' [<<exprNoAssign>>] procModifier* [('=' | ':') initializer]
|
||||||
// | ':=' initializer
|
// | ':=' initializer
|
||||||
// | '::' initializer
|
// | '::' initializer
|
||||||
static boolean declTail_(PsiBuilder builder_, int level_) {
|
static boolean declTail_(PsiBuilder builder_, int level_) {
|
||||||
@@ -386,7 +405,7 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ':' [<<exprNoAssign>>] [('=' | ':') initializer]
|
// ':' [<<exprNoAssign>>] procModifier* [('=' | ':') initializer]
|
||||||
private static boolean declTail__0(PsiBuilder builder_, int level_) {
|
private static boolean declTail__0(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "declTail__0")) return false;
|
if (!recursion_guard_(builder_, level_, "declTail__0")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
@@ -394,6 +413,7 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
result_ = consumeToken(builder_, COLON);
|
result_ = consumeToken(builder_, COLON);
|
||||||
result_ = result_ && declTail__0_1(builder_, level_ + 1);
|
result_ = result_ && declTail__0_1(builder_, level_ + 1);
|
||||||
result_ = result_ && declTail__0_2(builder_, level_ + 1);
|
result_ = result_ && declTail__0_2(builder_, level_ + 1);
|
||||||
|
result_ = result_ && declTail__0_3(builder_, level_ + 1);
|
||||||
exit_section_(builder_, marker_, null, result_);
|
exit_section_(builder_, marker_, null, result_);
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
@@ -405,27 +425,38 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [('=' | ':') initializer]
|
// procModifier*
|
||||||
private static boolean declTail__0_2(PsiBuilder builder_, int level_) {
|
private static boolean declTail__0_2(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "declTail__0_2")) return false;
|
if (!recursion_guard_(builder_, level_, "declTail__0_2")) return false;
|
||||||
declTail__0_2_0(builder_, level_ + 1);
|
while (true) {
|
||||||
|
int pos_ = current_position_(builder_);
|
||||||
|
if (!procModifier(builder_, level_ + 1)) break;
|
||||||
|
if (!empty_element_parsed_guard_(builder_, "declTail__0_2", pos_)) break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [('=' | ':') initializer]
|
||||||
|
private static boolean declTail__0_3(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "declTail__0_3")) return false;
|
||||||
|
declTail__0_3_0(builder_, level_ + 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ('=' | ':') initializer
|
// ('=' | ':') initializer
|
||||||
private static boolean declTail__0_2_0(PsiBuilder builder_, int level_) {
|
private static boolean declTail__0_3_0(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "declTail__0_2_0")) return false;
|
if (!recursion_guard_(builder_, level_, "declTail__0_3_0")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
Marker marker_ = enter_section_(builder_);
|
Marker marker_ = enter_section_(builder_);
|
||||||
result_ = declTail__0_2_0_0(builder_, level_ + 1);
|
result_ = declTail__0_3_0_0(builder_, level_ + 1);
|
||||||
result_ = result_ && initializer(builder_, level_ + 1);
|
result_ = result_ && initializer(builder_, level_ + 1);
|
||||||
exit_section_(builder_, marker_, null, result_);
|
exit_section_(builder_, marker_, null, result_);
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// '=' | ':'
|
// '=' | ':'
|
||||||
private static boolean declTail__0_2_0_0(PsiBuilder builder_, int level_) {
|
private static boolean declTail__0_3_0_0(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "declTail__0_2_0_0")) return false;
|
if (!recursion_guard_(builder_, level_, "declTail__0_3_0_0")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
result_ = consumeToken(builder_, EQ);
|
result_ = consumeToken(builder_, EQ);
|
||||||
if (!result_) result_ = consumeToken(builder_, COLON);
|
if (!result_) result_ = consumeToken(builder_, COLON);
|
||||||
@@ -455,7 +486,7 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// <<isDeclarationAhead>> declModifier_* declNames declTail_ NOTE* semi
|
// <<isDeclarationAhead>> declModifier_* declNames declTail_ semiWithNotes_
|
||||||
public static boolean declaration(PsiBuilder builder_, int level_) {
|
public static boolean declaration(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "declaration")) return false;
|
if (!recursion_guard_(builder_, level_, "declaration")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
@@ -464,8 +495,7 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
result_ = result_ && declaration_1(builder_, level_ + 1);
|
result_ = result_ && declaration_1(builder_, level_ + 1);
|
||||||
result_ = result_ && declNames(builder_, level_ + 1);
|
result_ = result_ && declNames(builder_, level_ + 1);
|
||||||
result_ = result_ && declTail_(builder_, level_ + 1);
|
result_ = result_ && declTail_(builder_, level_ + 1);
|
||||||
result_ = result_ && declaration_4(builder_, level_ + 1);
|
result_ = result_ && semiWithNotes_(builder_, level_ + 1);
|
||||||
result_ = result_ && semi(builder_, level_ + 1);
|
|
||||||
exit_section_(builder_, level_, marker_, result_, false, null);
|
exit_section_(builder_, level_, marker_, result_, false, null);
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
@@ -481,17 +511,6 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE*
|
|
||||||
private static boolean declaration_4(PsiBuilder builder_, int level_) {
|
|
||||||
if (!recursion_guard_(builder_, level_, "declaration_4")) return false;
|
|
||||||
while (true) {
|
|
||||||
int pos_ = current_position_(builder_);
|
|
||||||
if (!consumeToken(builder_, NOTE)) break;
|
|
||||||
if (!empty_element_parsed_guard_(builder_, "declaration_4", pos_)) break;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// ['`'] 'defer' statement
|
// ['`'] 'defer' statement
|
||||||
public static boolean deferStatement(PsiBuilder builder_, int level_) {
|
public static boolean deferStatement(PsiBuilder builder_, int level_) {
|
||||||
@@ -514,10 +533,12 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// <<dir "#assert">> expr [expr]
|
// <<dir "#asm">> directiveFlag_* <<opaqueBlock>>
|
||||||
// | <<dirWithBlock>> [',' IDENT] block
|
// | <<dir "#assert">> expr [expr]
|
||||||
// | <<dirWithOperand>> [',' IDENT] [expr]
|
// | <<dir "#module_parameters">> '(' [paramList] ')' ['(' [paramList] ')'] [block]
|
||||||
// | <<dirPlain>> [',' IDENT]
|
// | <<dirWithBlock>> directiveFlag_* block
|
||||||
|
// | <<dirWithOperand>> directiveFlag_* [expr]
|
||||||
|
// | <<dirPlain>> directiveFlag_*
|
||||||
public static boolean directiveExpr(PsiBuilder builder_, int level_) {
|
public static boolean directiveExpr(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "directiveExpr")) return false;
|
if (!recursion_guard_(builder_, level_, "directiveExpr")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
@@ -526,94 +547,198 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
if (!result_) result_ = directiveExpr_1(builder_, level_ + 1);
|
if (!result_) result_ = directiveExpr_1(builder_, level_ + 1);
|
||||||
if (!result_) result_ = directiveExpr_2(builder_, level_ + 1);
|
if (!result_) result_ = directiveExpr_2(builder_, level_ + 1);
|
||||||
if (!result_) result_ = directiveExpr_3(builder_, level_ + 1);
|
if (!result_) result_ = directiveExpr_3(builder_, level_ + 1);
|
||||||
|
if (!result_) result_ = directiveExpr_4(builder_, level_ + 1);
|
||||||
|
if (!result_) result_ = directiveExpr_5(builder_, level_ + 1);
|
||||||
exit_section_(builder_, level_, marker_, result_, false, null);
|
exit_section_(builder_, level_, marker_, result_, false, null);
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// <<dir "#assert">> expr [expr]
|
// <<dir "#asm">> directiveFlag_* <<opaqueBlock>>
|
||||||
private static boolean directiveExpr_0(PsiBuilder builder_, int level_) {
|
private static boolean directiveExpr_0(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "directiveExpr_0")) return false;
|
if (!recursion_guard_(builder_, level_, "directiveExpr_0")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
Marker marker_ = enter_section_(builder_);
|
Marker marker_ = enter_section_(builder_);
|
||||||
|
result_ = dir(builder_, level_ + 1, "#asm");
|
||||||
|
result_ = result_ && directiveExpr_0_1(builder_, level_ + 1);
|
||||||
|
result_ = result_ && opaqueBlock(builder_, level_ + 1);
|
||||||
|
exit_section_(builder_, marker_, null, result_);
|
||||||
|
return result_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// directiveFlag_*
|
||||||
|
private static boolean directiveExpr_0_1(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "directiveExpr_0_1")) return false;
|
||||||
|
while (true) {
|
||||||
|
int pos_ = current_position_(builder_);
|
||||||
|
if (!directiveFlag_(builder_, level_ + 1)) break;
|
||||||
|
if (!empty_element_parsed_guard_(builder_, "directiveExpr_0_1", pos_)) break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <<dir "#assert">> expr [expr]
|
||||||
|
private static boolean directiveExpr_1(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "directiveExpr_1")) return false;
|
||||||
|
boolean result_;
|
||||||
|
Marker marker_ = enter_section_(builder_);
|
||||||
result_ = dir(builder_, level_ + 1, "#assert");
|
result_ = dir(builder_, level_ + 1, "#assert");
|
||||||
result_ = result_ && expr(builder_, level_ + 1, -1);
|
result_ = result_ && expr(builder_, level_ + 1, -1);
|
||||||
result_ = result_ && directiveExpr_0_2(builder_, level_ + 1);
|
result_ = result_ && directiveExpr_1_2(builder_, level_ + 1);
|
||||||
exit_section_(builder_, marker_, null, result_);
|
exit_section_(builder_, marker_, null, result_);
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [expr]
|
// [expr]
|
||||||
private static boolean directiveExpr_0_2(PsiBuilder builder_, int level_) {
|
private static boolean directiveExpr_1_2(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "directiveExpr_0_2")) return false;
|
if (!recursion_guard_(builder_, level_, "directiveExpr_1_2")) return false;
|
||||||
expr(builder_, level_ + 1, -1);
|
expr(builder_, level_ + 1, -1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// <<dirWithBlock>> [',' IDENT] block
|
// <<dir "#module_parameters">> '(' [paramList] ')' ['(' [paramList] ')'] [block]
|
||||||
private static boolean directiveExpr_1(PsiBuilder builder_, int level_) {
|
private static boolean directiveExpr_2(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "directiveExpr_1")) return false;
|
if (!recursion_guard_(builder_, level_, "directiveExpr_2")) return false;
|
||||||
|
boolean result_;
|
||||||
|
Marker marker_ = enter_section_(builder_);
|
||||||
|
result_ = dir(builder_, level_ + 1, "#module_parameters");
|
||||||
|
result_ = result_ && consumeToken(builder_, LPAREN);
|
||||||
|
result_ = result_ && directiveExpr_2_2(builder_, level_ + 1);
|
||||||
|
result_ = result_ && consumeToken(builder_, RPAREN);
|
||||||
|
result_ = result_ && directiveExpr_2_4(builder_, level_ + 1);
|
||||||
|
result_ = result_ && directiveExpr_2_5(builder_, level_ + 1);
|
||||||
|
exit_section_(builder_, marker_, null, result_);
|
||||||
|
return result_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [paramList]
|
||||||
|
private static boolean directiveExpr_2_2(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "directiveExpr_2_2")) return false;
|
||||||
|
paramList(builder_, level_ + 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ['(' [paramList] ')']
|
||||||
|
private static boolean directiveExpr_2_4(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "directiveExpr_2_4")) return false;
|
||||||
|
directiveExpr_2_4_0(builder_, level_ + 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// '(' [paramList] ')'
|
||||||
|
private static boolean directiveExpr_2_4_0(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "directiveExpr_2_4_0")) return false;
|
||||||
|
boolean result_;
|
||||||
|
Marker marker_ = enter_section_(builder_);
|
||||||
|
result_ = consumeToken(builder_, LPAREN);
|
||||||
|
result_ = result_ && directiveExpr_2_4_0_1(builder_, level_ + 1);
|
||||||
|
result_ = result_ && consumeToken(builder_, RPAREN);
|
||||||
|
exit_section_(builder_, marker_, null, result_);
|
||||||
|
return result_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [paramList]
|
||||||
|
private static boolean directiveExpr_2_4_0_1(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "directiveExpr_2_4_0_1")) return false;
|
||||||
|
paramList(builder_, level_ + 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [block]
|
||||||
|
private static boolean directiveExpr_2_5(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "directiveExpr_2_5")) return false;
|
||||||
|
block(builder_, level_ + 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <<dirWithBlock>> directiveFlag_* block
|
||||||
|
private static boolean directiveExpr_3(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "directiveExpr_3")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
Marker marker_ = enter_section_(builder_);
|
Marker marker_ = enter_section_(builder_);
|
||||||
result_ = dirWithBlock(builder_, level_ + 1);
|
result_ = dirWithBlock(builder_, level_ + 1);
|
||||||
result_ = result_ && directiveExpr_1_1(builder_, level_ + 1);
|
result_ = result_ && directiveExpr_3_1(builder_, level_ + 1);
|
||||||
result_ = result_ && block(builder_, level_ + 1);
|
result_ = result_ && block(builder_, level_ + 1);
|
||||||
exit_section_(builder_, marker_, null, result_);
|
exit_section_(builder_, marker_, null, result_);
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [',' IDENT]
|
// directiveFlag_*
|
||||||
private static boolean directiveExpr_1_1(PsiBuilder builder_, int level_) {
|
private static boolean directiveExpr_3_1(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "directiveExpr_1_1")) return false;
|
if (!recursion_guard_(builder_, level_, "directiveExpr_3_1")) return false;
|
||||||
parseTokens(builder_, 0, COMMA, IDENT);
|
while (true) {
|
||||||
|
int pos_ = current_position_(builder_);
|
||||||
|
if (!directiveFlag_(builder_, level_ + 1)) break;
|
||||||
|
if (!empty_element_parsed_guard_(builder_, "directiveExpr_3_1", pos_)) break;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// <<dirWithOperand>> [',' IDENT] [expr]
|
// <<dirWithOperand>> directiveFlag_* [expr]
|
||||||
private static boolean directiveExpr_2(PsiBuilder builder_, int level_) {
|
private static boolean directiveExpr_4(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "directiveExpr_2")) return false;
|
if (!recursion_guard_(builder_, level_, "directiveExpr_4")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
Marker marker_ = enter_section_(builder_);
|
Marker marker_ = enter_section_(builder_);
|
||||||
result_ = dirWithOperand(builder_, level_ + 1);
|
result_ = dirWithOperand(builder_, level_ + 1);
|
||||||
result_ = result_ && directiveExpr_2_1(builder_, level_ + 1);
|
result_ = result_ && directiveExpr_4_1(builder_, level_ + 1);
|
||||||
result_ = result_ && directiveExpr_2_2(builder_, level_ + 1);
|
result_ = result_ && directiveExpr_4_2(builder_, level_ + 1);
|
||||||
exit_section_(builder_, marker_, null, result_);
|
exit_section_(builder_, marker_, null, result_);
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [',' IDENT]
|
// directiveFlag_*
|
||||||
private static boolean directiveExpr_2_1(PsiBuilder builder_, int level_) {
|
private static boolean directiveExpr_4_1(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "directiveExpr_2_1")) return false;
|
if (!recursion_guard_(builder_, level_, "directiveExpr_4_1")) return false;
|
||||||
parseTokens(builder_, 0, COMMA, IDENT);
|
while (true) {
|
||||||
|
int pos_ = current_position_(builder_);
|
||||||
|
if (!directiveFlag_(builder_, level_ + 1)) break;
|
||||||
|
if (!empty_element_parsed_guard_(builder_, "directiveExpr_4_1", pos_)) break;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [expr]
|
// [expr]
|
||||||
private static boolean directiveExpr_2_2(PsiBuilder builder_, int level_) {
|
private static boolean directiveExpr_4_2(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "directiveExpr_2_2")) return false;
|
if (!recursion_guard_(builder_, level_, "directiveExpr_4_2")) return false;
|
||||||
expr(builder_, level_ + 1, -1);
|
expr(builder_, level_ + 1, -1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// <<dirPlain>> [',' IDENT]
|
// <<dirPlain>> directiveFlag_*
|
||||||
private static boolean directiveExpr_3(PsiBuilder builder_, int level_) {
|
private static boolean directiveExpr_5(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "directiveExpr_3")) return false;
|
if (!recursion_guard_(builder_, level_, "directiveExpr_5")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
Marker marker_ = enter_section_(builder_);
|
Marker marker_ = enter_section_(builder_);
|
||||||
result_ = dirPlain(builder_, level_ + 1);
|
result_ = dirPlain(builder_, level_ + 1);
|
||||||
result_ = result_ && directiveExpr_3_1(builder_, level_ + 1);
|
result_ = result_ && directiveExpr_5_1(builder_, level_ + 1);
|
||||||
exit_section_(builder_, marker_, null, result_);
|
exit_section_(builder_, marker_, null, result_);
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [',' IDENT]
|
// directiveFlag_*
|
||||||
private static boolean directiveExpr_3_1(PsiBuilder builder_, int level_) {
|
private static boolean directiveExpr_5_1(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "directiveExpr_3_1")) return false;
|
if (!recursion_guard_(builder_, level_, "directiveExpr_5_1")) return false;
|
||||||
parseTokens(builder_, 0, COMMA, IDENT);
|
while (true) {
|
||||||
|
int pos_ = current_position_(builder_);
|
||||||
|
if (!directiveFlag_(builder_, level_ + 1)) break;
|
||||||
|
if (!empty_element_parsed_guard_(builder_, "directiveExpr_5_1", pos_)) break;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// <<dirBare>> [',' IDENT] [';']
|
// ',' IDENT
|
||||||
|
static boolean directiveFlag_(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "directiveFlag_")) return false;
|
||||||
|
if (!nextTokenIs(builder_, COMMA)) return false;
|
||||||
|
boolean result_;
|
||||||
|
Marker marker_ = enter_section_(builder_);
|
||||||
|
result_ = consumeTokens(builder_, 0, COMMA, IDENT);
|
||||||
|
exit_section_(builder_, marker_, null, result_);
|
||||||
|
return result_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ********************************************************** */
|
||||||
|
// <<dirBare>> directiveFlag_* [';']
|
||||||
public static boolean directiveStatement(PsiBuilder builder_, int level_) {
|
public static boolean directiveStatement(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "directiveStatement")) return false;
|
if (!recursion_guard_(builder_, level_, "directiveStatement")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
@@ -625,10 +750,14 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [',' IDENT]
|
// directiveFlag_*
|
||||||
private static boolean directiveStatement_1(PsiBuilder builder_, int level_) {
|
private static boolean directiveStatement_1(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "directiveStatement_1")) return false;
|
if (!recursion_guard_(builder_, level_, "directiveStatement_1")) return false;
|
||||||
parseTokens(builder_, 0, COMMA, IDENT);
|
while (true) {
|
||||||
|
int pos_ = current_position_(builder_);
|
||||||
|
if (!directiveFlag_(builder_, level_ + 1)) break;
|
||||||
|
if (!empty_element_parsed_guard_(builder_, "directiveStatement_1", pos_)) break;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -716,15 +845,14 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// expr (',' expr)* NOTE* semi
|
// expr (',' expr)* semiWithNotes_
|
||||||
public static boolean expressionStatement(PsiBuilder builder_, int level_) {
|
public static boolean expressionStatement(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "expressionStatement")) return false;
|
if (!recursion_guard_(builder_, level_, "expressionStatement")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
Marker marker_ = enter_section_(builder_, level_, _NONE_, EXPRESSION_STATEMENT, "<expression statement>");
|
Marker marker_ = enter_section_(builder_, level_, _NONE_, EXPRESSION_STATEMENT, "<expression statement>");
|
||||||
result_ = expr(builder_, level_ + 1, -1);
|
result_ = expr(builder_, level_ + 1, -1);
|
||||||
result_ = result_ && expressionStatement_1(builder_, level_ + 1);
|
result_ = result_ && expressionStatement_1(builder_, level_ + 1);
|
||||||
result_ = result_ && expressionStatement_2(builder_, level_ + 1);
|
result_ = result_ && semiWithNotes_(builder_, level_ + 1);
|
||||||
result_ = result_ && semi(builder_, level_ + 1);
|
|
||||||
exit_section_(builder_, level_, marker_, result_, false, null);
|
exit_section_(builder_, level_, marker_, result_, false, null);
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
@@ -751,17 +879,6 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE*
|
|
||||||
private static boolean expressionStatement_2(PsiBuilder builder_, int level_) {
|
|
||||||
if (!recursion_guard_(builder_, level_, "expressionStatement_2")) return false;
|
|
||||||
while (true) {
|
|
||||||
int pos_ = current_position_(builder_);
|
|
||||||
if (!consumeToken(builder_, NOTE)) break;
|
|
||||||
if (!empty_element_parsed_guard_(builder_, "expressionStatement_2", pos_)) break;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// '<' | '*'
|
// '<' | '*'
|
||||||
static boolean forModifier_(PsiBuilder builder_, int level_) {
|
static boolean forModifier_(PsiBuilder builder_, int level_) {
|
||||||
@@ -1069,7 +1186,7 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// 'operator' operatorSymbol '::' expr NOTE* semi
|
// 'operator' operatorSymbol '::' expr semiWithNotes_
|
||||||
public static boolean operatorDeclaration(PsiBuilder builder_, int level_) {
|
public static boolean operatorDeclaration(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "operatorDeclaration")) return false;
|
if (!recursion_guard_(builder_, level_, "operatorDeclaration")) return false;
|
||||||
if (!nextTokenIs(builder_, KW_OPERATOR)) return false;
|
if (!nextTokenIs(builder_, KW_OPERATOR)) return false;
|
||||||
@@ -1079,23 +1196,11 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
result_ = result_ && operatorSymbol(builder_, level_ + 1);
|
result_ = result_ && operatorSymbol(builder_, level_ + 1);
|
||||||
result_ = result_ && consumeToken(builder_, COLON_COLON);
|
result_ = result_ && consumeToken(builder_, COLON_COLON);
|
||||||
result_ = result_ && expr(builder_, level_ + 1, -1);
|
result_ = result_ && expr(builder_, level_ + 1, -1);
|
||||||
result_ = result_ && operatorDeclaration_4(builder_, level_ + 1);
|
result_ = result_ && semiWithNotes_(builder_, level_ + 1);
|
||||||
result_ = result_ && semi(builder_, level_ + 1);
|
|
||||||
exit_section_(builder_, marker_, OPERATOR_DECLARATION, result_);
|
exit_section_(builder_, marker_, OPERATOR_DECLARATION, result_);
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE*
|
|
||||||
private static boolean operatorDeclaration_4(PsiBuilder builder_, int level_) {
|
|
||||||
if (!recursion_guard_(builder_, level_, "operatorDeclaration_4")) return false;
|
|
||||||
while (true) {
|
|
||||||
int pos_ = current_position_(builder_);
|
|
||||||
if (!consumeToken(builder_, NOTE)) break;
|
|
||||||
if (!empty_element_parsed_guard_(builder_, "operatorDeclaration_4", pos_)) break;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// '+' | '-' | '*' | '/' | '%' | '==' | '!=' | '<' | '>' | '<=' | '>='
|
// '+' | '-' | '*' | '/' | '%' | '==' | '!=' | '<' | '>' | '<=' | '>='
|
||||||
// | '&' | '|' | '^' | '~' | '<<' | '>>' | '<<<' | '>>>'
|
// | '&' | '|' | '^' | '~' | '<<' | '>>' | '<<<' | '>>>'
|
||||||
@@ -1171,6 +1276,18 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ********************************************************** */
|
||||||
|
// <<dirPlain>> | 'using'
|
||||||
|
static boolean paramModifier_(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "paramModifier_")) return false;
|
||||||
|
boolean result_;
|
||||||
|
Marker marker_ = enter_section_(builder_);
|
||||||
|
result_ = dirPlain(builder_, level_ + 1);
|
||||||
|
if (!result_) result_ = consumeToken(builder_, KW_USING);
|
||||||
|
exit_section_(builder_, marker_, null, result_);
|
||||||
|
return result_;
|
||||||
|
}
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// ['$' | '$$'] IDENT
|
// ['$' | '$$'] IDENT
|
||||||
public static boolean paramName(PsiBuilder builder_, int level_) {
|
public static boolean paramName(PsiBuilder builder_, int level_) {
|
||||||
@@ -1308,7 +1425,7 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// ['using'] parameterTail_
|
// paramModifier_* parameterTail_
|
||||||
public static boolean parameter(PsiBuilder builder_, int level_) {
|
public static boolean parameter(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "parameter")) return false;
|
if (!recursion_guard_(builder_, level_, "parameter")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
@@ -1319,10 +1436,14 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ['using']
|
// paramModifier_*
|
||||||
private static boolean parameter_0(PsiBuilder builder_, int level_) {
|
private static boolean parameter_0(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "parameter_0")) return false;
|
if (!recursion_guard_(builder_, level_, "parameter_0")) return false;
|
||||||
consumeToken(builder_, KW_USING);
|
while (true) {
|
||||||
|
int pos_ = current_position_(builder_);
|
||||||
|
if (!paramModifier_(builder_, level_ + 1)) break;
|
||||||
|
if (!empty_element_parsed_guard_(builder_, "parameter_0", pos_)) break;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1527,9 +1648,9 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// <<dirWithBlock>> block
|
// <<dirWithBlock>> directiveFlag_* block
|
||||||
// | <<dirWithOperand>> [',' IDENT] [expr]
|
// | <<dirWithOperand>> directiveFlag_* [expr]
|
||||||
// | <<dirPlain>> [',' IDENT]
|
// | <<dirPlain>> directiveFlag_*
|
||||||
public static boolean procModifier(PsiBuilder builder_, int level_) {
|
public static boolean procModifier(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "procModifier")) return false;
|
if (!recursion_guard_(builder_, level_, "procModifier")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
@@ -1541,18 +1662,30 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// <<dirWithBlock>> block
|
// <<dirWithBlock>> directiveFlag_* block
|
||||||
private static boolean procModifier_0(PsiBuilder builder_, int level_) {
|
private static boolean procModifier_0(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "procModifier_0")) return false;
|
if (!recursion_guard_(builder_, level_, "procModifier_0")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
Marker marker_ = enter_section_(builder_);
|
Marker marker_ = enter_section_(builder_);
|
||||||
result_ = dirWithBlock(builder_, level_ + 1);
|
result_ = dirWithBlock(builder_, level_ + 1);
|
||||||
|
result_ = result_ && procModifier_0_1(builder_, level_ + 1);
|
||||||
result_ = result_ && block(builder_, level_ + 1);
|
result_ = result_ && block(builder_, level_ + 1);
|
||||||
exit_section_(builder_, marker_, null, result_);
|
exit_section_(builder_, marker_, null, result_);
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// <<dirWithOperand>> [',' IDENT] [expr]
|
// directiveFlag_*
|
||||||
|
private static boolean procModifier_0_1(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "procModifier_0_1")) return false;
|
||||||
|
while (true) {
|
||||||
|
int pos_ = current_position_(builder_);
|
||||||
|
if (!directiveFlag_(builder_, level_ + 1)) break;
|
||||||
|
if (!empty_element_parsed_guard_(builder_, "procModifier_0_1", pos_)) break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <<dirWithOperand>> directiveFlag_* [expr]
|
||||||
private static boolean procModifier_1(PsiBuilder builder_, int level_) {
|
private static boolean procModifier_1(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "procModifier_1")) return false;
|
if (!recursion_guard_(builder_, level_, "procModifier_1")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
@@ -1564,10 +1697,14 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [',' IDENT]
|
// directiveFlag_*
|
||||||
private static boolean procModifier_1_1(PsiBuilder builder_, int level_) {
|
private static boolean procModifier_1_1(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "procModifier_1_1")) return false;
|
if (!recursion_guard_(builder_, level_, "procModifier_1_1")) return false;
|
||||||
parseTokens(builder_, 0, COMMA, IDENT);
|
while (true) {
|
||||||
|
int pos_ = current_position_(builder_);
|
||||||
|
if (!directiveFlag_(builder_, level_ + 1)) break;
|
||||||
|
if (!empty_element_parsed_guard_(builder_, "procModifier_1_1", pos_)) break;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1578,7 +1715,7 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// <<dirPlain>> [',' IDENT]
|
// <<dirPlain>> directiveFlag_*
|
||||||
private static boolean procModifier_2(PsiBuilder builder_, int level_) {
|
private static boolean procModifier_2(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "procModifier_2")) return false;
|
if (!recursion_guard_(builder_, level_, "procModifier_2")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
@@ -1589,10 +1726,14 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [',' IDENT]
|
// directiveFlag_*
|
||||||
private static boolean procModifier_2_1(PsiBuilder builder_, int level_) {
|
private static boolean procModifier_2_1(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "procModifier_2_1")) return false;
|
if (!recursion_guard_(builder_, level_, "procModifier_2_1")) return false;
|
||||||
parseTokens(builder_, 0, COMMA, IDENT);
|
while (true) {
|
||||||
|
int pos_ = current_position_(builder_);
|
||||||
|
if (!directiveFlag_(builder_, level_ + 1)) break;
|
||||||
|
if (!empty_element_parsed_guard_(builder_, "procModifier_2_1", pos_)) break;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1706,14 +1847,13 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// [<<isParamNameAhead>> IDENT ':'] <<exprNoAssign>> ['=' initializer]
|
// [<<isParamNameAhead>> IDENT ':'] <<exprNoAssign>>
|
||||||
public static boolean returnItem(PsiBuilder builder_, int level_) {
|
public static boolean returnItem(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "returnItem")) return false;
|
if (!recursion_guard_(builder_, level_, "returnItem")) return false;
|
||||||
boolean result_;
|
boolean result_;
|
||||||
Marker marker_ = enter_section_(builder_, level_, _NONE_, RETURN_ITEM, "<return item>");
|
Marker marker_ = enter_section_(builder_, level_, _NONE_, RETURN_ITEM, "<return item>");
|
||||||
result_ = returnItem_0(builder_, level_ + 1);
|
result_ = returnItem_0(builder_, level_ + 1);
|
||||||
result_ = result_ && exprNoAssign(builder_, level_ + 1);
|
result_ = result_ && exprNoAssign(builder_, level_ + 1);
|
||||||
result_ = result_ && returnItem_2(builder_, level_ + 1);
|
|
||||||
exit_section_(builder_, level_, marker_, result_, false, null);
|
exit_section_(builder_, level_, marker_, result_, false, null);
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
@@ -1736,26 +1876,8 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ['=' initializer]
|
|
||||||
private static boolean returnItem_2(PsiBuilder builder_, int level_) {
|
|
||||||
if (!recursion_guard_(builder_, level_, "returnItem_2")) return false;
|
|
||||||
returnItem_2_0(builder_, level_ + 1);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// '=' initializer
|
|
||||||
private static boolean returnItem_2_0(PsiBuilder builder_, int level_) {
|
|
||||||
if (!recursion_guard_(builder_, level_, "returnItem_2_0")) return false;
|
|
||||||
boolean result_;
|
|
||||||
Marker marker_ = enter_section_(builder_);
|
|
||||||
result_ = consumeToken(builder_, EQ);
|
|
||||||
result_ = result_ && initializer(builder_, level_ + 1);
|
|
||||||
exit_section_(builder_, marker_, null, result_);
|
|
||||||
return result_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// 'return' [expr (',' expr)*] NOTE* semi
|
// 'return' [expr (',' expr)*] semiWithNotes_
|
||||||
public static boolean returnStatement(PsiBuilder builder_, int level_) {
|
public static boolean returnStatement(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "returnStatement")) return false;
|
if (!recursion_guard_(builder_, level_, "returnStatement")) return false;
|
||||||
if (!nextTokenIs(builder_, KW_RETURN)) return false;
|
if (!nextTokenIs(builder_, KW_RETURN)) return false;
|
||||||
@@ -1763,8 +1885,7 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
Marker marker_ = enter_section_(builder_);
|
Marker marker_ = enter_section_(builder_);
|
||||||
result_ = consumeToken(builder_, KW_RETURN);
|
result_ = consumeToken(builder_, KW_RETURN);
|
||||||
result_ = result_ && returnStatement_1(builder_, level_ + 1);
|
result_ = result_ && returnStatement_1(builder_, level_ + 1);
|
||||||
result_ = result_ && returnStatement_2(builder_, level_ + 1);
|
result_ = result_ && semiWithNotes_(builder_, level_ + 1);
|
||||||
result_ = result_ && semi(builder_, level_ + 1);
|
|
||||||
exit_section_(builder_, marker_, RETURN_STATEMENT, result_);
|
exit_section_(builder_, marker_, RETURN_STATEMENT, result_);
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
@@ -1809,17 +1930,6 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE*
|
|
||||||
private static boolean returnStatement_2(PsiBuilder builder_, int level_) {
|
|
||||||
if (!recursion_guard_(builder_, level_, "returnStatement_2")) return false;
|
|
||||||
while (true) {
|
|
||||||
int pos_ = current_position_(builder_);
|
|
||||||
if (!consumeToken(builder_, NOTE)) break;
|
|
||||||
if (!empty_element_parsed_guard_(builder_, "returnStatement_2", pos_)) break;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// <<isReturnGroupAhead>> returnGroup | returnItem (',' returnItem)*
|
// <<isReturnGroupAhead>> returnGroup | returnItem (',' returnItem)*
|
||||||
static boolean returnTypes_(PsiBuilder builder_, int level_) {
|
static boolean returnTypes_(PsiBuilder builder_, int level_) {
|
||||||
@@ -1888,6 +1998,62 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ********************************************************** */
|
||||||
|
// <<prevEndsConstruct>> NOTE* | NOTE* ';'
|
||||||
|
static boolean semiWithNotes_(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "semiWithNotes_")) return false;
|
||||||
|
boolean result_;
|
||||||
|
Marker marker_ = enter_section_(builder_);
|
||||||
|
result_ = semiWithNotes__0(builder_, level_ + 1);
|
||||||
|
if (!result_) result_ = semiWithNotes__1(builder_, level_ + 1);
|
||||||
|
exit_section_(builder_, marker_, null, result_);
|
||||||
|
return result_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <<prevEndsConstruct>> NOTE*
|
||||||
|
private static boolean semiWithNotes__0(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "semiWithNotes__0")) return false;
|
||||||
|
boolean result_;
|
||||||
|
Marker marker_ = enter_section_(builder_);
|
||||||
|
result_ = prevEndsConstruct(builder_, level_ + 1);
|
||||||
|
result_ = result_ && semiWithNotes__0_1(builder_, level_ + 1);
|
||||||
|
exit_section_(builder_, marker_, null, result_);
|
||||||
|
return result_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE*
|
||||||
|
private static boolean semiWithNotes__0_1(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "semiWithNotes__0_1")) return false;
|
||||||
|
while (true) {
|
||||||
|
int pos_ = current_position_(builder_);
|
||||||
|
if (!consumeToken(builder_, NOTE)) break;
|
||||||
|
if (!empty_element_parsed_guard_(builder_, "semiWithNotes__0_1", pos_)) break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE* ';'
|
||||||
|
private static boolean semiWithNotes__1(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "semiWithNotes__1")) return false;
|
||||||
|
boolean result_;
|
||||||
|
Marker marker_ = enter_section_(builder_);
|
||||||
|
result_ = semiWithNotes__1_0(builder_, level_ + 1);
|
||||||
|
result_ = result_ && consumeToken(builder_, SEMICOLON);
|
||||||
|
exit_section_(builder_, marker_, null, result_);
|
||||||
|
return result_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE*
|
||||||
|
private static boolean semiWithNotes__1_0(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "semiWithNotes__1_0")) return false;
|
||||||
|
while (true) {
|
||||||
|
int pos_ = current_position_(builder_);
|
||||||
|
if (!consumeToken(builder_, NOTE)) break;
|
||||||
|
if (!empty_element_parsed_guard_(builder_, "semiWithNotes__1_0", pos_)) break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// ';'
|
// ';'
|
||||||
// | block
|
// | block
|
||||||
@@ -1903,8 +2069,8 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
// | operatorDeclaration
|
// | operatorDeclaration
|
||||||
// | usingStatement
|
// | usingStatement
|
||||||
// | noteStatement
|
// | noteStatement
|
||||||
// | directiveStatement
|
|
||||||
// | declaration
|
// | declaration
|
||||||
|
// | directiveStatement
|
||||||
// | expressionStatement
|
// | expressionStatement
|
||||||
public static boolean statement(PsiBuilder builder_, int level_) {
|
public static boolean statement(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "statement")) return false;
|
if (!recursion_guard_(builder_, level_, "statement")) return false;
|
||||||
@@ -1924,8 +2090,8 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
if (!result_) result_ = operatorDeclaration(builder_, level_ + 1);
|
if (!result_) result_ = operatorDeclaration(builder_, level_ + 1);
|
||||||
if (!result_) result_ = usingStatement(builder_, level_ + 1);
|
if (!result_) result_ = usingStatement(builder_, level_ + 1);
|
||||||
if (!result_) result_ = noteStatement(builder_, level_ + 1);
|
if (!result_) result_ = noteStatement(builder_, level_ + 1);
|
||||||
if (!result_) result_ = directiveStatement(builder_, level_ + 1);
|
|
||||||
if (!result_) result_ = declaration(builder_, level_ + 1);
|
if (!result_) result_ = declaration(builder_, level_ + 1);
|
||||||
|
if (!result_) result_ = directiveStatement(builder_, level_ + 1);
|
||||||
if (!result_) result_ = expressionStatement(builder_, level_ + 1);
|
if (!result_) result_ = expressionStatement(builder_, level_ + 1);
|
||||||
exit_section_(builder_, level_, marker_, result_, false, null);
|
exit_section_(builder_, level_, marker_, result_, false, null);
|
||||||
return result_;
|
return result_;
|
||||||
@@ -2169,24 +2335,26 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
// 11: BINARY(addExpr)
|
// 11: BINARY(addExpr)
|
||||||
// 12: BINARY(mulExpr)
|
// 12: BINARY(mulExpr)
|
||||||
// 13: PREFIX(prefixExpr)
|
// 13: PREFIX(prefixExpr)
|
||||||
// 14: ATOM(arrayTypeExpr)
|
// 14: PREFIX(derefCastExpr)
|
||||||
// 15: ATOM(castExpr)
|
// 15: ATOM(arrayTypeExpr)
|
||||||
// 16: PREFIX(autoCastExpr)
|
// 16: ATOM(castExpr)
|
||||||
// 17: PREFIX(inlineExpr)
|
// 17: PREFIX(autoCastExpr)
|
||||||
// 18: ATOM(ifxExpr)
|
// 18: PREFIX(inlineExpr)
|
||||||
// 19: POSTFIX(callExpr)
|
// 19: ATOM(ifxExpr)
|
||||||
// 20: POSTFIX(indexExpr)
|
// 20: POSTFIX(callExpr)
|
||||||
// 21: POSTFIX(memberExpr)
|
// 21: POSTFIX(indexExpr)
|
||||||
// 22: POSTFIX(derefExpr)
|
// 22: POSTFIX(memberExpr)
|
||||||
// 23: POSTFIX(typedStructLiteralExpr)
|
// 23: POSTFIX(derefExpr)
|
||||||
// 24: POSTFIX(typedArrayLiteralExpr)
|
// 24: POSTFIX(typedStructLiteralExpr)
|
||||||
// 25: ATOM(primaryExpr)
|
// 25: POSTFIX(typedArrayLiteralExpr)
|
||||||
|
// 26: ATOM(primaryExpr)
|
||||||
public static boolean expr(PsiBuilder builder_, int level_, int priority_) {
|
public static boolean expr(PsiBuilder builder_, int level_, int priority_) {
|
||||||
if (!recursion_guard_(builder_, level_, "expr")) return false;
|
if (!recursion_guard_(builder_, level_, "expr")) return false;
|
||||||
addVariant(builder_, "<expr>");
|
addVariant(builder_, "<expr>");
|
||||||
boolean result_, pinned_;
|
boolean result_, pinned_;
|
||||||
Marker marker_ = enter_section_(builder_, level_, _NONE_, "<expr>");
|
Marker marker_ = enter_section_(builder_, level_, _NONE_, "<expr>");
|
||||||
result_ = prefixExpr(builder_, level_ + 1);
|
result_ = prefixExpr(builder_, level_ + 1);
|
||||||
|
if (!result_) result_ = derefCastExpr(builder_, level_ + 1);
|
||||||
if (!result_) result_ = arrayTypeExpr(builder_, level_ + 1);
|
if (!result_) result_ = arrayTypeExpr(builder_, level_ + 1);
|
||||||
if (!result_) result_ = castExpr(builder_, level_ + 1);
|
if (!result_) result_ = castExpr(builder_, level_ + 1);
|
||||||
if (!result_) result_ = autoCastExpr(builder_, level_ + 1);
|
if (!result_) result_ = autoCastExpr(builder_, level_ + 1);
|
||||||
@@ -2256,27 +2424,27 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
result_ = expr(builder_, level_, 12);
|
result_ = expr(builder_, level_, 12);
|
||||||
exit_section_(builder_, level_, marker_, MUL_EXPR, result_, true, null);
|
exit_section_(builder_, level_, marker_, MUL_EXPR, result_, true, null);
|
||||||
}
|
}
|
||||||
else if (priority_ < 19 && callExpr_0(builder_, level_ + 1)) {
|
else if (priority_ < 20 && callExpr_0(builder_, level_ + 1)) {
|
||||||
result_ = true;
|
result_ = true;
|
||||||
exit_section_(builder_, level_, marker_, CALL_EXPR, result_, true, null);
|
exit_section_(builder_, level_, marker_, CALL_EXPR, result_, true, null);
|
||||||
}
|
}
|
||||||
else if (priority_ < 20 && indexExpr_0(builder_, level_ + 1)) {
|
else if (priority_ < 21 && indexExpr_0(builder_, level_ + 1)) {
|
||||||
result_ = true;
|
result_ = true;
|
||||||
exit_section_(builder_, level_, marker_, INDEX_EXPR, result_, true, null);
|
exit_section_(builder_, level_, marker_, INDEX_EXPR, result_, true, null);
|
||||||
}
|
}
|
||||||
else if (priority_ < 21 && memberExpr_0(builder_, level_ + 1)) {
|
else if (priority_ < 22 && memberExpr_0(builder_, level_ + 1)) {
|
||||||
result_ = true;
|
result_ = true;
|
||||||
exit_section_(builder_, level_, marker_, MEMBER_EXPR, result_, true, null);
|
exit_section_(builder_, level_, marker_, MEMBER_EXPR, result_, true, null);
|
||||||
}
|
}
|
||||||
else if (priority_ < 22 && consumeTokenSmart(builder_, POSTFIX_DEREFERENCE)) {
|
else if (priority_ < 23 && consumeTokenSmart(builder_, POSTFIX_DEREFERENCE)) {
|
||||||
result_ = true;
|
result_ = true;
|
||||||
exit_section_(builder_, level_, marker_, DEREF_EXPR, result_, true, null);
|
exit_section_(builder_, level_, marker_, DEREF_EXPR, result_, true, null);
|
||||||
}
|
}
|
||||||
else if (priority_ < 23 && typedStructLiteralExpr_0(builder_, level_ + 1)) {
|
else if (priority_ < 24 && typedStructLiteralExpr_0(builder_, level_ + 1)) {
|
||||||
result_ = true;
|
result_ = true;
|
||||||
exit_section_(builder_, level_, marker_, TYPED_STRUCT_LITERAL_EXPR, result_, true, null);
|
exit_section_(builder_, level_, marker_, TYPED_STRUCT_LITERAL_EXPR, result_, true, null);
|
||||||
}
|
}
|
||||||
else if (priority_ < 24 && typedArrayLiteralExpr_0(builder_, level_ + 1)) {
|
else if (priority_ < 25 && typedArrayLiteralExpr_0(builder_, level_ + 1)) {
|
||||||
result_ = true;
|
result_ = true;
|
||||||
exit_section_(builder_, level_, marker_, TYPED_ARRAY_LITERAL_EXPR, result_, true, null);
|
exit_section_(builder_, level_, marker_, TYPED_ARRAY_LITERAL_EXPR, result_, true, null);
|
||||||
}
|
}
|
||||||
@@ -2352,6 +2520,18 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
return result_ || pinned_;
|
return result_ || pinned_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean derefCastExpr(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "derefCastExpr")) return false;
|
||||||
|
if (!nextTokenIsSmart(builder_, LPAREN)) return false;
|
||||||
|
boolean result_, pinned_;
|
||||||
|
Marker marker_ = enter_section_(builder_, level_, _NONE_, null);
|
||||||
|
result_ = parseTokensSmart(builder_, 0, LPAREN, POSTFIX_DEREFERENCE, RPAREN);
|
||||||
|
pinned_ = result_;
|
||||||
|
result_ = pinned_ && expr(builder_, level_, 14);
|
||||||
|
exit_section_(builder_, level_, marker_, DEREF_CAST_EXPR, result_, pinned_, null);
|
||||||
|
return result_ || pinned_;
|
||||||
|
}
|
||||||
|
|
||||||
// '[' ['..' | expr] ']' expr
|
// '[' ['..' | expr] ']' expr
|
||||||
public static boolean arrayTypeExpr(PsiBuilder builder_, int level_) {
|
public static boolean arrayTypeExpr(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "arrayTypeExpr")) return false;
|
if (!recursion_guard_(builder_, level_, "arrayTypeExpr")) return false;
|
||||||
@@ -2419,7 +2599,7 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
Marker marker_ = enter_section_(builder_, level_, _NONE_, null);
|
Marker marker_ = enter_section_(builder_, level_, _NONE_, null);
|
||||||
result_ = autoCastExpr_0(builder_, level_ + 1);
|
result_ = autoCastExpr_0(builder_, level_ + 1);
|
||||||
pinned_ = result_;
|
pinned_ = result_;
|
||||||
result_ = pinned_ && expr(builder_, level_, 16);
|
result_ = pinned_ && expr(builder_, level_, 17);
|
||||||
exit_section_(builder_, level_, marker_, AUTO_CAST_EXPR, result_, pinned_, null);
|
exit_section_(builder_, level_, marker_, AUTO_CAST_EXPR, result_, pinned_, null);
|
||||||
return result_ || pinned_;
|
return result_ || pinned_;
|
||||||
}
|
}
|
||||||
@@ -2449,7 +2629,7 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
Marker marker_ = enter_section_(builder_, level_, _NONE_, null);
|
Marker marker_ = enter_section_(builder_, level_, _NONE_, null);
|
||||||
result_ = inlineExpr_0(builder_, level_ + 1);
|
result_ = inlineExpr_0(builder_, level_ + 1);
|
||||||
pinned_ = result_;
|
pinned_ = result_;
|
||||||
result_ = pinned_ && expr(builder_, level_, 17);
|
result_ = pinned_ && expr(builder_, level_, 18);
|
||||||
exit_section_(builder_, level_, marker_, INLINE_EXPR, result_, pinned_, null);
|
exit_section_(builder_, level_, marker_, INLINE_EXPR, result_, pinned_, null);
|
||||||
return result_ || pinned_;
|
return result_ || pinned_;
|
||||||
}
|
}
|
||||||
@@ -2463,7 +2643,7 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'ifx' expr ['then'] expr ['else' expr]
|
// 'ifx' expr ['then'] [expr] ['else' expr]
|
||||||
public static boolean ifxExpr(PsiBuilder builder_, int level_) {
|
public static boolean ifxExpr(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "ifxExpr")) return false;
|
if (!recursion_guard_(builder_, level_, "ifxExpr")) return false;
|
||||||
if (!nextTokenIsSmart(builder_, KW_IFX)) return false;
|
if (!nextTokenIsSmart(builder_, KW_IFX)) return false;
|
||||||
@@ -2472,7 +2652,7 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
result_ = consumeTokenSmart(builder_, KW_IFX);
|
result_ = consumeTokenSmart(builder_, KW_IFX);
|
||||||
result_ = result_ && expr(builder_, level_ + 1, -1);
|
result_ = result_ && expr(builder_, level_ + 1, -1);
|
||||||
result_ = result_ && ifxExpr_2(builder_, level_ + 1);
|
result_ = result_ && ifxExpr_2(builder_, level_ + 1);
|
||||||
result_ = result_ && expr(builder_, level_ + 1, -1);
|
result_ = result_ && ifxExpr_3(builder_, level_ + 1);
|
||||||
result_ = result_ && ifxExpr_4(builder_, level_ + 1);
|
result_ = result_ && ifxExpr_4(builder_, level_ + 1);
|
||||||
exit_section_(builder_, marker_, IFX_EXPR, result_);
|
exit_section_(builder_, marker_, IFX_EXPR, result_);
|
||||||
return result_;
|
return result_;
|
||||||
@@ -2485,6 +2665,13 @@ public class JaiParser implements PsiParser, LightPsiParser {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [expr]
|
||||||
|
private static boolean ifxExpr_3(PsiBuilder builder_, int level_) {
|
||||||
|
if (!recursion_guard_(builder_, level_, "ifxExpr_3")) return false;
|
||||||
|
expr(builder_, level_ + 1, -1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// ['else' expr]
|
// ['else' expr]
|
||||||
private static boolean ifxExpr_4(PsiBuilder builder_, int level_) {
|
private static boolean ifxExpr_4(PsiBuilder builder_, int level_) {
|
||||||
if (!recursion_guard_(builder_, level_, "ifxExpr_4")) return false;
|
if (!recursion_guard_(builder_, level_, "ifxExpr_4")) return false;
|
||||||
|
|||||||
10
src/main/gen/dev/hgh/jai/psi/JaiDeclName.java
Normal file
10
src/main/gen/dev/hgh/jai/psi/JaiDeclName.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
// This is a generated file. Not intended for manual editing.
|
||||||
|
package dev.hgh.jai.psi;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import org.jetbrains.annotations.*;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
|
||||||
|
public interface JaiDeclName extends PsiElement {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,4 +7,7 @@ import com.intellij.psi.PsiElement;
|
|||||||
|
|
||||||
public interface JaiDeclNames extends PsiElement {
|
public interface JaiDeclNames extends PsiElement {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
List<JaiDeclName> getDeclNameList();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,4 +13,7 @@ public interface JaiDeclaration extends PsiElement {
|
|||||||
@Nullable
|
@Nullable
|
||||||
JaiInitializer getInitializer();
|
JaiInitializer getInitializer();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
List<JaiProcModifier> getProcModifierList();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
13
src/main/gen/dev/hgh/jai/psi/JaiDerefCastExpr.java
Normal file
13
src/main/gen/dev/hgh/jai/psi/JaiDerefCastExpr.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
// This is a generated file. Not intended for manual editing.
|
||||||
|
package dev.hgh.jai.psi;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import org.jetbrains.annotations.*;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
|
||||||
|
public interface JaiDerefCastExpr extends JaiExpr {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
JaiExpr getExpr();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -13,4 +13,7 @@ public interface JaiDirectiveExpr extends JaiExpr {
|
|||||||
@NotNull
|
@NotNull
|
||||||
List<JaiExpr> getExprList();
|
List<JaiExpr> getExprList();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
List<JaiParameter> getParameterList();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,4 @@ import com.intellij.psi.PsiElement;
|
|||||||
|
|
||||||
public interface JaiReturnItem extends PsiElement {
|
public interface JaiReturnItem extends PsiElement {
|
||||||
|
|
||||||
@Nullable
|
|
||||||
JaiInitializer getInitializer();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,10 @@ public interface JaiTypes {
|
|||||||
IElementType CAST_EXPR = new JaiElementType("CAST_EXPR");
|
IElementType CAST_EXPR = new JaiElementType("CAST_EXPR");
|
||||||
IElementType CONTINUE_STATEMENT = new JaiElementType("CONTINUE_STATEMENT");
|
IElementType CONTINUE_STATEMENT = new JaiElementType("CONTINUE_STATEMENT");
|
||||||
IElementType DECLARATION = new JaiElementType("DECLARATION");
|
IElementType DECLARATION = new JaiElementType("DECLARATION");
|
||||||
|
IElementType DECL_NAME = new JaiElementType("DECL_NAME");
|
||||||
IElementType DECL_NAMES = new JaiElementType("DECL_NAMES");
|
IElementType DECL_NAMES = new JaiElementType("DECL_NAMES");
|
||||||
IElementType DEFER_STATEMENT = new JaiElementType("DEFER_STATEMENT");
|
IElementType DEFER_STATEMENT = new JaiElementType("DEFER_STATEMENT");
|
||||||
|
IElementType DEREF_CAST_EXPR = new JaiElementType("DEREF_CAST_EXPR");
|
||||||
IElementType DEREF_EXPR = new JaiElementType("DEREF_EXPR");
|
IElementType DEREF_EXPR = new JaiElementType("DEREF_EXPR");
|
||||||
IElementType DIRECTIVE_EXPR = new JaiElementType("DIRECTIVE_EXPR");
|
IElementType DIRECTIVE_EXPR = new JaiElementType("DIRECTIVE_EXPR");
|
||||||
IElementType DIRECTIVE_STATEMENT = new JaiElementType("DIRECTIVE_STATEMENT");
|
IElementType DIRECTIVE_STATEMENT = new JaiElementType("DIRECTIVE_STATEMENT");
|
||||||
@@ -253,12 +255,18 @@ public interface JaiTypes {
|
|||||||
else if (type == DECLARATION) {
|
else if (type == DECLARATION) {
|
||||||
return new JaiDeclarationImpl(node);
|
return new JaiDeclarationImpl(node);
|
||||||
}
|
}
|
||||||
|
else if (type == DECL_NAME) {
|
||||||
|
return new JaiDeclNameImpl(node);
|
||||||
|
}
|
||||||
else if (type == DECL_NAMES) {
|
else if (type == DECL_NAMES) {
|
||||||
return new JaiDeclNamesImpl(node);
|
return new JaiDeclNamesImpl(node);
|
||||||
}
|
}
|
||||||
else if (type == DEFER_STATEMENT) {
|
else if (type == DEFER_STATEMENT) {
|
||||||
return new JaiDeferStatementImpl(node);
|
return new JaiDeferStatementImpl(node);
|
||||||
}
|
}
|
||||||
|
else if (type == DEREF_CAST_EXPR) {
|
||||||
|
return new JaiDerefCastExprImpl(node);
|
||||||
|
}
|
||||||
else if (type == DEREF_EXPR) {
|
else if (type == DEREF_EXPR) {
|
||||||
return new JaiDerefExprImpl(node);
|
return new JaiDerefExprImpl(node);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,10 @@ public class JaiVisitor extends PsiElementVisitor {
|
|||||||
visitPsiElement(o);
|
visitPsiElement(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void visitDeclName(@NotNull JaiDeclName o) {
|
||||||
|
visitPsiElement(o);
|
||||||
|
}
|
||||||
|
|
||||||
public void visitDeclNames(@NotNull JaiDeclNames o) {
|
public void visitDeclNames(@NotNull JaiDeclNames o) {
|
||||||
visitPsiElement(o);
|
visitPsiElement(o);
|
||||||
}
|
}
|
||||||
@@ -91,6 +95,10 @@ public class JaiVisitor extends PsiElementVisitor {
|
|||||||
visitPsiElement(o);
|
visitPsiElement(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void visitDerefCastExpr(@NotNull JaiDerefCastExpr o) {
|
||||||
|
visitExpr(o);
|
||||||
|
}
|
||||||
|
|
||||||
public void visitDerefExpr(@NotNull JaiDerefExpr o) {
|
public void visitDerefExpr(@NotNull JaiDerefExpr o) {
|
||||||
visitExpr(o);
|
visitExpr(o);
|
||||||
}
|
}
|
||||||
|
|||||||
30
src/main/gen/dev/hgh/jai/psi/impl/JaiDeclNameImpl.java
Normal file
30
src/main/gen/dev/hgh/jai/psi/impl/JaiDeclNameImpl.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
// This is a generated file. Not intended for manual editing.
|
||||||
|
package dev.hgh.jai.psi.impl;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import org.jetbrains.annotations.*;
|
||||||
|
import com.intellij.lang.ASTNode;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.psi.PsiElementVisitor;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
|
import static dev.hgh.jai.psi.JaiTypes.*;
|
||||||
|
import com.intellij.extapi.psi.ASTWrapperPsiElement;
|
||||||
|
import dev.hgh.jai.psi.*;
|
||||||
|
|
||||||
|
public class JaiDeclNameImpl extends ASTWrapperPsiElement implements JaiDeclName {
|
||||||
|
|
||||||
|
public JaiDeclNameImpl(@NotNull ASTNode node) {
|
||||||
|
super(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void accept(@NotNull JaiVisitor visitor) {
|
||||||
|
visitor.visitDeclName(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||||
|
if (visitor instanceof JaiVisitor) accept((JaiVisitor)visitor);
|
||||||
|
else super.accept(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -27,4 +27,10 @@ public class JaiDeclNamesImpl extends ASTWrapperPsiElement implements JaiDeclNam
|
|||||||
else super.accept(visitor);
|
else super.accept(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public List<JaiDeclName> getDeclNameList() {
|
||||||
|
return PsiTreeUtil.getChildrenOfTypeAsList(this, JaiDeclName.class);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,4 +39,10 @@ public class JaiDeclarationImpl extends ASTWrapperPsiElement implements JaiDecla
|
|||||||
return findChildByClass(JaiInitializer.class);
|
return findChildByClass(JaiInitializer.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public List<JaiProcModifier> getProcModifierList() {
|
||||||
|
return PsiTreeUtil.getChildrenOfTypeAsList(this, JaiProcModifier.class);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
36
src/main/gen/dev/hgh/jai/psi/impl/JaiDerefCastExprImpl.java
Normal file
36
src/main/gen/dev/hgh/jai/psi/impl/JaiDerefCastExprImpl.java
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
// This is a generated file. Not intended for manual editing.
|
||||||
|
package dev.hgh.jai.psi.impl;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import org.jetbrains.annotations.*;
|
||||||
|
import com.intellij.lang.ASTNode;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.psi.PsiElementVisitor;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
|
import static dev.hgh.jai.psi.JaiTypes.*;
|
||||||
|
import dev.hgh.jai.psi.*;
|
||||||
|
|
||||||
|
public class JaiDerefCastExprImpl extends JaiExprImpl implements JaiDerefCastExpr {
|
||||||
|
|
||||||
|
public JaiDerefCastExprImpl(@NotNull ASTNode node) {
|
||||||
|
super(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(@NotNull JaiVisitor visitor) {
|
||||||
|
visitor.visitDerefCastExpr(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||||
|
if (visitor instanceof JaiVisitor) accept((JaiVisitor)visitor);
|
||||||
|
else super.accept(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public JaiExpr getExpr() {
|
||||||
|
return findChildByClass(JaiExpr.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -39,4 +39,10 @@ public class JaiDirectiveExprImpl extends JaiExprImpl implements JaiDirectiveExp
|
|||||||
return PsiTreeUtil.getChildrenOfTypeAsList(this, JaiExpr.class);
|
return PsiTreeUtil.getChildrenOfTypeAsList(this, JaiExpr.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public List<JaiParameter> getParameterList() {
|
||||||
|
return PsiTreeUtil.getChildrenOfTypeAsList(this, JaiParameter.class);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,10 +27,4 @@ public class JaiReturnItemImpl extends ASTWrapperPsiElement implements JaiReturn
|
|||||||
else super.accept(visitor);
|
else super.accept(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public JaiInitializer getInitializer() {
|
|
||||||
return findChildByClass(JaiInitializer.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,8 +156,8 @@ statement ::= ';'
|
|||||||
| operatorDeclaration
|
| operatorDeclaration
|
||||||
| usingStatement
|
| usingStatement
|
||||||
| noteStatement
|
| noteStatement
|
||||||
| directiveStatement
|
|
||||||
| declaration
|
| declaration
|
||||||
|
| directiveStatement
|
||||||
| expressionStatement
|
| expressionStatement
|
||||||
|
|
||||||
block ::= '{' statement* '}'
|
block ::= '{' statement* '}'
|
||||||
@@ -167,13 +167,17 @@ block ::= '{' statement* '}'
|
|||||||
// `BODY :: #string DONE … DONE`. `x := 1` still needs one.
|
// `BODY :: #string DONE … DONE`. `x := 1` still needs one.
|
||||||
private semi ::= ';' | <<prevEndsConstruct>>
|
private semi ::= ';' | <<prevEndsConstruct>>
|
||||||
|
|
||||||
|
// Notes attach to the end of a declaration or statement. `<<prevEndsConstruct>>` has
|
||||||
|
// to be checked *before* the notes, because `} @NoProfile` ends at the `}`.
|
||||||
|
private semiWithNotes_ ::= <<prevEndsConstruct>> NOTE* | NOTE* ';'
|
||||||
|
|
||||||
noteStatement ::= NOTE+
|
noteStatement ::= NOTE+
|
||||||
|
|
||||||
// `#scope_file`, `#no_padding`, `#placeholder foo` … a directive that takes no operand
|
// `#scope_file`, `#no_padding`, `#placeholder foo` … a directive that takes no operand
|
||||||
// is a statement on its own and carries no `;`. Directives that *do* take an operand
|
// is a statement on its own and carries no `;`. Directives that *do* take an operand
|
||||||
// (`#run f()`, `#import "Basic"`) fall through to expressionStatement, which requires
|
// (`#run f()`, `#import "Basic"`) fall through to expressionStatement, which requires
|
||||||
// one.
|
// one.
|
||||||
directiveStatement ::= <<dirBare>> [',' IDENT] [';']
|
directiveStatement ::= <<dirBare>> directiveFlag_* [';']
|
||||||
|
|
||||||
// `#if` is spelled as a directive but is structurally an `if`, and it pairs with the
|
// `#if` is spelled as a directive but is structurally an `if`, and it pairs with the
|
||||||
// ordinary `else` keyword (see modules/File_Watcher/module.jai).
|
// ordinary `else` keyword (see modules/File_Watcher/module.jai).
|
||||||
@@ -194,7 +198,7 @@ forStatement ::= 'for' [':' expr] forModifier_* [<<isForNamesAhead>> forNames ':
|
|||||||
private forModifier_ ::= '<' | '*'
|
private forModifier_ ::= '<' | '*'
|
||||||
forNames ::= IDENT (',' IDENT)*
|
forNames ::= IDENT (',' IDENT)*
|
||||||
|
|
||||||
returnStatement ::= 'return' [expr (',' expr)*] NOTE* semi
|
returnStatement ::= 'return' [expr (',' expr)*] semiWithNotes_
|
||||||
breakStatement ::= 'break' [IDENT] semi
|
breakStatement ::= 'break' [IDENT] semi
|
||||||
continueStatement ::= 'continue' [IDENT] semi
|
continueStatement ::= 'continue' [IDENT] semi
|
||||||
removeStatement ::= 'remove' [expr] semi
|
removeStatement ::= 'remove' [expr] semi
|
||||||
@@ -202,23 +206,25 @@ deferStatement ::= ['`'] 'defer' statement
|
|||||||
pushContextStatement ::= ['`'] 'push_context' expr block
|
pushContextStatement ::= ['`'] 'push_context' expr block
|
||||||
usingStatement ::= 'using' [',' expr] expr semi
|
usingStatement ::= 'using' [',' expr] expr semi
|
||||||
|
|
||||||
expressionStatement ::= expr (',' expr)* NOTE* semi
|
expressionStatement ::= expr (',' expr)* semiWithNotes_
|
||||||
|
|
||||||
// ------------------------------------------------------------------- declarations
|
// ------------------------------------------------------------------- declarations
|
||||||
|
|
||||||
// Jai has no declaration keyword: `a : int = 1`, `a := 1`, `a :: 1`, `Foo :: struct {}`
|
// Jai has no declaration keyword: `a : int = 1`, `a := 1`, `a :: 1`, `Foo :: struct {}`
|
||||||
// and `main :: () {}` are all the same shape. The guard is what separates them from
|
// and `main :: () {}` are all the same shape. The guard is what separates them from
|
||||||
// an expression statement such as `foo();`.
|
// an expression statement such as `foo();`.
|
||||||
declaration ::= <<isDeclarationAhead>> declModifier_* declNames declTail_ NOTE* semi
|
declaration ::= <<isDeclarationAhead>> declModifier_* declNames declTail_ semiWithNotes_
|
||||||
private declModifier_ ::= <<dirPlain>> | 'using'
|
// `#as using base: Document;`, `#overlay (unknown.vtable) using vtable: *Vtable;`
|
||||||
declNames ::= IDENT (',' IDENT)*
|
private declModifier_ ::= procModifier | 'using'
|
||||||
private declTail_ ::= ':' [<<exprNoAssign>>] [('=' | ':') initializer]
|
declNames ::= declName (',' declName)*
|
||||||
|
declName ::= ['`'] IDENT
|
||||||
|
private declTail_ ::= ':' [<<exprNoAssign>>] procModifier* [('=' | ':') initializer]
|
||||||
| ':=' initializer
|
| ':=' initializer
|
||||||
| '::' initializer
|
| '::' initializer
|
||||||
initializer ::= '---' | expr
|
initializer ::= '---' | expr
|
||||||
|
|
||||||
// `operator + :: (a: T, b: T) -> T { }`
|
// `operator + :: (a: T, b: T) -> T { }`
|
||||||
operatorDeclaration ::= 'operator' operatorSymbol '::' expr NOTE* semi
|
operatorDeclaration ::= 'operator' operatorSymbol '::' expr semiWithNotes_
|
||||||
operatorSymbol ::= '+' | '-' | '*' | '/' | '%' | '==' | '!=' | '<' | '>' | '<=' | '>='
|
operatorSymbol ::= '+' | '-' | '*' | '/' | '%' | '==' | '!=' | '<' | '>' | '<=' | '>='
|
||||||
| '&' | '|' | '^' | '~' | '<<' | '>>' | '<<<' | '>>>'
|
| '&' | '|' | '^' | '~' | '<<' | '>>' | '<<<' | '>>>'
|
||||||
| '[' ']' | '[' ']' '='
|
| '[' ']' | '[' ']' '='
|
||||||
@@ -239,6 +245,7 @@ expr ::= assignExpr
|
|||||||
| addExpr
|
| addExpr
|
||||||
| mulExpr
|
| mulExpr
|
||||||
| prefixExpr
|
| prefixExpr
|
||||||
|
| derefCastExpr
|
||||||
| arrayTypeExpr
|
| arrayTypeExpr
|
||||||
| castExpr
|
| castExpr
|
||||||
| autoCastExpr
|
| autoCastExpr
|
||||||
@@ -279,10 +286,14 @@ private prefixOp_ ::= '-' | '+' | '!' | '~' | '*' | '..' | '$' | '$$' | '<<' | '
|
|||||||
// element type. Distinct from indexExpr, which needs a left operand.
|
// element type. Distinct from indexExpr, which needs a left operand.
|
||||||
arrayTypeExpr ::= '[' ['..' | expr] ']' expr
|
arrayTypeExpr ::= '[' ['..' | expr] ']' expr
|
||||||
|
|
||||||
|
// `(.*) cast(*u32) p` — the postfix dereference written prefix-style in parentheses
|
||||||
|
// (modules/Shared_Memory_Channel/module.jai:113).
|
||||||
|
derefCastExpr ::= '(' '.*' ')' expr
|
||||||
|
|
||||||
castExpr ::= 'cast' [',' IDENT] '(' [expr] ')' expr
|
castExpr ::= 'cast' [',' IDENT] '(' [expr] ')' expr
|
||||||
autoCastExpr ::= 'xx' [',' IDENT] expr
|
autoCastExpr ::= 'xx' [',' IDENT] expr
|
||||||
inlineExpr ::= ('inline' | 'no_inline') expr
|
inlineExpr ::= ('inline' | 'no_inline') expr
|
||||||
ifxExpr ::= 'ifx' expr ['then'] expr ['else' expr]
|
ifxExpr ::= 'ifx' expr ['then'] [expr] ['else' expr]
|
||||||
|
|
||||||
callExpr ::= expr '(' [argList] ')'
|
callExpr ::= expr '(' [argList] ')'
|
||||||
indexExpr ::= expr '[' [expr] ']'
|
indexExpr ::= expr '[' [expr] ']'
|
||||||
@@ -339,7 +350,8 @@ procLiteralExpr ::= <<isProcHeaderAhead>> '(' [paramList] ')' ['->' returnTypes_
|
|||||||
| '->' returnTypes_ procModifier* [block]
|
| '->' returnTypes_ procModifier* [block]
|
||||||
|
|
||||||
private paramList ::= parameter (',' parameter)* [',']
|
private paramList ::= parameter (',' parameter)* [',']
|
||||||
parameter ::= ['using'] parameterTail_
|
parameter ::= paramModifier_* parameterTail_
|
||||||
|
private paramModifier_ ::= <<dirPlain>> | 'using'
|
||||||
private parameterTail_ ::= <<isParamNameAhead>> paramNames paramTypeTail_ | '..' | expr
|
private parameterTail_ ::= <<isParamNameAhead>> paramNames paramTypeTail_ | '..' | expr
|
||||||
paramNames ::= paramName (',' paramName)*
|
paramNames ::= paramName (',' paramName)*
|
||||||
paramName ::= ['$' | '$$'] IDENT
|
paramName ::= ['$' | '$$'] IDENT
|
||||||
@@ -349,12 +361,12 @@ private paramTypeTail_ ::= ':' [<<exprNoAssign>>] ['=' initializer]
|
|||||||
|
|
||||||
private returnTypes_ ::= <<isReturnGroupAhead>> returnGroup | returnItem (',' returnItem)*
|
private returnTypes_ ::= <<isReturnGroupAhead>> returnGroup | returnItem (',' returnItem)*
|
||||||
returnGroup ::= '(' [returnItem (',' returnItem)*] ')'
|
returnGroup ::= '(' [returnItem (',' returnItem)*] ')'
|
||||||
returnItem ::= [<<isParamNameAhead>> IDENT ':'] <<exprNoAssign>> ['=' initializer]
|
returnItem ::= [<<isParamNameAhead>> IDENT ':'] <<exprNoAssign>>
|
||||||
|
|
||||||
// `#foreign lib`, `#modify { ... }`, `#c_call`, `#expand`, …
|
// `#foreign lib`, `#modify { ... }`, `#c_call`, `#expand`, …
|
||||||
procModifier ::= <<dirWithBlock>> block
|
procModifier ::= <<dirWithBlock>> directiveFlag_* block
|
||||||
| <<dirWithOperand>> [',' IDENT] [expr]
|
| <<dirWithOperand>> directiveFlag_* [expr]
|
||||||
| <<dirPlain>> [',' IDENT]
|
| <<dirPlain>> directiveFlag_*
|
||||||
|
|
||||||
structExpr ::= 'struct' ['(' [paramList] ')'] structModifier_* block
|
structExpr ::= 'struct' ['(' [paramList] ')'] structModifier_* block
|
||||||
enumExpr ::= ('enum' | 'enum_flags') [!'{' expr] structModifier_* block
|
enumExpr ::= ('enum' | 'enum_flags') [!'{' expr] structModifier_* block
|
||||||
@@ -365,7 +377,13 @@ private structModifier_ ::= procModifier
|
|||||||
|
|
||||||
// `#ident` is one token, so which directives take operands is decided in
|
// `#ident` is one token, so which directives take operands is decided in
|
||||||
// JaiParserUtil rather than here.
|
// JaiParserUtil rather than here.
|
||||||
directiveExpr ::= <<dir "#assert">> expr [expr]
|
directiveExpr ::= <<dir "#asm">> directiveFlag_* <<opaqueBlock>>
|
||||||
| <<dirWithBlock>> [',' IDENT] block
|
| <<dir "#assert">> expr [expr]
|
||||||
| <<dirWithOperand>> [',' IDENT] [expr]
|
| <<dir "#module_parameters">> '(' [paramList] ')' ['(' [paramList] ')'] [block]
|
||||||
| <<dirPlain>> [',' IDENT]
|
| <<dirWithBlock>> directiveFlag_* block
|
||||||
|
| <<dirWithOperand>> directiveFlag_* [expr]
|
||||||
|
| <<dirPlain>> directiveFlag_*
|
||||||
|
|
||||||
|
// `#import,file`, `#library,system,link_always`, `#run,stallable` — a directive can
|
||||||
|
// carry any number of comma-separated flags.
|
||||||
|
private directiveFlag_ ::= ',' IDENT
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ object JaiParserUtil : GeneratedParserUtilBase() {
|
|||||||
"add_context",
|
"add_context",
|
||||||
"module_parameters",
|
"module_parameters",
|
||||||
"place",
|
"place",
|
||||||
|
"overlay",
|
||||||
"procedure_of_call",
|
"procedure_of_call",
|
||||||
"body_text",
|
"body_text",
|
||||||
"version",
|
"version",
|
||||||
@@ -85,7 +86,6 @@ object JaiParserUtil : GeneratedParserUtilBase() {
|
|||||||
"elsewhere",
|
"elsewhere",
|
||||||
"expand",
|
"expand",
|
||||||
"specified",
|
"specified",
|
||||||
"discard",
|
|
||||||
"location",
|
"location",
|
||||||
"this",
|
"this",
|
||||||
)
|
)
|
||||||
@@ -286,9 +286,13 @@ object JaiParserUtil : GeneratedParserUtilBase() {
|
|||||||
): Boolean = b.tokenType === T.LPAREN && !isProcHeaderAhead(b, level)
|
): Boolean = b.tokenType === T.LPAREN && !isProcHeaderAhead(b, level)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `[#directive|using]* IDENT (',' IDENT)* (':' | '::' | ':=')` — a declaration.
|
* `[#directive [(…)] | using | `]* IDENT (',' IDENT)* (':' | '::' | ':=')` — a
|
||||||
* Jai declarations have no introducer keyword, so this is what tells
|
* declaration. Jai declarations have no introducer keyword, so this is what tells
|
||||||
* `foo :: () {}` apart from `foo();`.
|
* `foo :: () {}` apart from `foo();`.
|
||||||
|
*
|
||||||
|
* The prefix skip covers `#as using base: Document;`,
|
||||||
|
* `#overlay (unknown.vtable) using vtable: *Vtable;` and the macro-exported
|
||||||
|
* `` `it := entry.value; ``.
|
||||||
*/
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun isDeclarationAhead(
|
fun isDeclarationAhead(
|
||||||
@@ -296,11 +300,24 @@ object JaiParserUtil : GeneratedParserUtilBase() {
|
|||||||
level: Int,
|
level: Int,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
var i = 0
|
var i = 0
|
||||||
while (true) {
|
loop@ while (true) {
|
||||||
val t = b.lookAhead(i) ?: return false
|
when (b.lookAhead(i)) {
|
||||||
if (t === T.DIRECTIVE || t === T.KW_USING) i++ else break
|
T.DIRECTIVE, T.KW_USING -> {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
T.LPAREN -> {
|
||||||
|
i = skipBalancedParens(b, i)
|
||||||
|
if (i < 0) return false
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
|
if (b.lookAhead(i) === T.BACKTICK) i++
|
||||||
if (b.lookAhead(i) !== T.IDENT) return false
|
if (b.lookAhead(i) !== T.IDENT) return false
|
||||||
i++
|
i++
|
||||||
when (b.lookAhead(i)) {
|
when (b.lookAhead(i)) {
|
||||||
@@ -311,6 +328,61 @@ object JaiParserUtil : GeneratedParserUtilBase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Index just past the `)` matching the `(` at [start], or -1 if unbalanced. */
|
||||||
|
private fun skipBalancedParens(
|
||||||
|
b: PsiBuilder,
|
||||||
|
start: Int,
|
||||||
|
): Int {
|
||||||
|
var depth = 0
|
||||||
|
var i = start
|
||||||
|
while (i - start <= MAX_LOOKAHEAD) {
|
||||||
|
when (b.lookAhead(i) ?: return -1) {
|
||||||
|
T.LPAREN -> {
|
||||||
|
depth++
|
||||||
|
}
|
||||||
|
|
||||||
|
T.RPAREN -> {
|
||||||
|
depth--
|
||||||
|
if (depth == 0) return i + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Consumes a `{ … }` block as opaque tokens.
|
||||||
|
*
|
||||||
|
* Used for `#asm`, whose body is x86-64 assembly (`movd source:, byte;`) and not
|
||||||
|
* Jai at all. Giving it structure is a separate job; tiling it keeps the
|
||||||
|
* surrounding file parseable.
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
fun opaqueBlock(
|
||||||
|
b: PsiBuilder,
|
||||||
|
level: Int,
|
||||||
|
): Boolean {
|
||||||
|
if (b.tokenType !== T.LBRACE) return false
|
||||||
|
var depth = 0
|
||||||
|
while (!b.eof()) {
|
||||||
|
val t = b.tokenType
|
||||||
|
if (t === T.LBRACE) {
|
||||||
|
depth++
|
||||||
|
} else if (t === T.RBRACE) {
|
||||||
|
depth--
|
||||||
|
if (depth == 0) {
|
||||||
|
b.advanceLexer()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.advanceLexer()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
/** `[$|$$] IDENT (',' [$|$$] IDENT)* (':' | '::' | ':=')` — a named parameter. */
|
/** `[$|$$] IDENT (',' [$|$$] IDENT)* (':' | '::' | ':=')` — a named parameter. */
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun isParamNameAhead(
|
fun isParamNameAhead(
|
||||||
|
|||||||
104
src/test/kotlin/dev/hgh/jai/parser/DebugParseTest.kt
Normal file
104
src/test/kotlin/dev/hgh/jai/parser/DebugParseTest.kt
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
package dev.hgh.jai.parser
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiErrorElement
|
||||||
|
import com.intellij.psi.PsiFileFactory
|
||||||
|
import com.intellij.psi.PsiRecursiveElementWalkingVisitor
|
||||||
|
import com.intellij.testFramework.fixtures.BasePlatformTestCase
|
||||||
|
import dev.hgh.jai.JaiLanguage
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scratch harness for grammar work. Not a gate — the gate is [JaiCorpusParserTest].
|
||||||
|
*
|
||||||
|
* Set `-Djai.debug.file=<path>` to dump every error in one corpus file instead.
|
||||||
|
*/
|
||||||
|
class DebugParseTest : BasePlatformTestCase() {
|
||||||
|
private val snippets =
|
||||||
|
listOf(
|
||||||
|
"tzname: **u8 #elsewhere libc;\n",
|
||||||
|
"S :: struct {\n #as unknown: IUnknown;\n}\n",
|
||||||
|
"x.magic = (.*) cast(*u32) DATA.data;\n",
|
||||||
|
"M :: #library,system,link_always \"Metal\";\n",
|
||||||
|
"f :: (s: *u8, \$strict := false) -> u32 { return 1; }\n",
|
||||||
|
"#module_parameters (MAX := 4, VERBOSE := false);\n",
|
||||||
|
"Allocator_Proc :: #type (mode: int, old: *void) -> *void;\n",
|
||||||
|
"SimpleProcedure :: #type () -> ();\n",
|
||||||
|
"n := tprint(\"%\", ifx options.output_path else \".\");\n",
|
||||||
|
"v :: (info: *File_Visit_Info, modules : *[..] string) { }\n",
|
||||||
|
"B :: struct (type: Type, by_pointer := false) { }\n",
|
||||||
|
"e := ifx a then b;\n",
|
||||||
|
)
|
||||||
|
|
||||||
|
/** Corpus files to dump the first error of; edit freely while working. */
|
||||||
|
private val corpusFiles =
|
||||||
|
listOf(
|
||||||
|
"modules/Sound_Player/os/win32.jai",
|
||||||
|
"examples/module_info.jai",
|
||||||
|
"how_to/800_allocators.jai",
|
||||||
|
"modules/POSIX/module.jai",
|
||||||
|
"modules/Basic/module.jai",
|
||||||
|
"modules/Compiler/module.jai",
|
||||||
|
"modules/Window_Creation/module.jai",
|
||||||
|
"modules/String/module.jai",
|
||||||
|
"modules/Hash_Table.jai",
|
||||||
|
"modules/Math/module.jai",
|
||||||
|
)
|
||||||
|
|
||||||
|
fun testCorpusFiles() {
|
||||||
|
val root = File(System.getProperty("user.home"), ".local/jai")
|
||||||
|
if (!root.exists()) return
|
||||||
|
for (relative in corpusFiles) {
|
||||||
|
val file = File(root, relative)
|
||||||
|
if (file.exists()) dumpFile(file) else println("missing: $relative")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testSnippets() {
|
||||||
|
val debugFile = System.getProperty("jai.debug.file")
|
||||||
|
if (debugFile != null) {
|
||||||
|
dumpFile(File(debugFile))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val factory = PsiFileFactory.getInstance(project)
|
||||||
|
var failures = 0
|
||||||
|
for (text in snippets) {
|
||||||
|
val file = factory.createFileFromText("t.jai", JaiLanguage, text)
|
||||||
|
val error = firstError(file)
|
||||||
|
if (error == null) {
|
||||||
|
println("ok ${text.replace("\n", "\\n")}")
|
||||||
|
} else {
|
||||||
|
failures++
|
||||||
|
val at = text.substring(error.textOffset).take(28).replace("\n", "\\n")
|
||||||
|
println("FAIL ${text.replace("\n", "\\n")}")
|
||||||
|
println(" ${error.errorDescription} | at '$at'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println("$failures/${snippets.size} snippets failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun dumpFile(file: File) {
|
||||||
|
val text = file.readText()
|
||||||
|
val psi = PsiFileFactory.getInstance(project).createFileFromText(file.name, JaiLanguage, text)
|
||||||
|
val error = firstError(psi)
|
||||||
|
if (error == null) {
|
||||||
|
println("${file.name}: clean")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val line = text.substring(0, error.textOffset).count { it == '\n' } + 1
|
||||||
|
println("${file.name}:$line: ${error.errorDescription}")
|
||||||
|
println(" at '${text.substring(error.textOffset).take(80).replace("\n", "\\n")}'")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun firstError(file: com.intellij.psi.PsiFile): PsiErrorElement? {
|
||||||
|
var first: PsiErrorElement? = null
|
||||||
|
file.accept(
|
||||||
|
object : PsiRecursiveElementWalkingVisitor() {
|
||||||
|
override fun visitErrorElement(element: PsiErrorElement) {
|
||||||
|
if (first == null) first = element
|
||||||
|
super.visitErrorElement(element)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return first
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,8 @@ Jai File(0,49)
|
|||||||
JaiStatementImpl(STATEMENT)(0,17)
|
JaiStatementImpl(STATEMENT)(0,17)
|
||||||
JaiDeclarationImpl(DECLARATION)(0,17)
|
JaiDeclarationImpl(DECLARATION)(0,17)
|
||||||
JaiDeclNamesImpl(DECL_NAMES)(0,1)
|
JaiDeclNamesImpl(DECL_NAMES)(0,1)
|
||||||
PsiElement(Jai:IDENT)('a')(0,1)
|
JaiDeclNameImpl(DECL_NAME)(0,1)
|
||||||
|
PsiElement(Jai:IDENT)('a')(0,1)
|
||||||
PsiElement(Jai::)(':')(2,3)
|
PsiElement(Jai::)(':')(2,3)
|
||||||
JaiRefExprImpl(REF_EXPR)(4,9)
|
JaiRefExprImpl(REF_EXPR)(4,9)
|
||||||
PsiElement(Jai:IDENT)('float')(4,9)
|
PsiElement(Jai:IDENT)('float')(4,9)
|
||||||
@@ -14,7 +15,8 @@ Jai File(0,49)
|
|||||||
JaiStatementImpl(STATEMENT)(18,26)
|
JaiStatementImpl(STATEMENT)(18,26)
|
||||||
JaiDeclarationImpl(DECLARATION)(18,26)
|
JaiDeclarationImpl(DECLARATION)(18,26)
|
||||||
JaiDeclNamesImpl(DECL_NAMES)(18,19)
|
JaiDeclNamesImpl(DECL_NAMES)(18,19)
|
||||||
PsiElement(Jai:IDENT)('b')(18,19)
|
JaiDeclNameImpl(DECL_NAME)(18,19)
|
||||||
|
PsiElement(Jai:IDENT)('b')(18,19)
|
||||||
PsiElement(Jai::=)(':=')(20,22)
|
PsiElement(Jai::=)(':=')(20,22)
|
||||||
JaiInitializerImpl(INITIALIZER)(23,25)
|
JaiInitializerImpl(INITIALIZER)(23,25)
|
||||||
JaiLiteralExprImpl(LITERAL_EXPR)(23,25)
|
JaiLiteralExprImpl(LITERAL_EXPR)(23,25)
|
||||||
@@ -23,7 +25,8 @@ Jai File(0,49)
|
|||||||
JaiStatementImpl(STATEMENT)(27,35)
|
JaiStatementImpl(STATEMENT)(27,35)
|
||||||
JaiDeclarationImpl(DECLARATION)(27,35)
|
JaiDeclarationImpl(DECLARATION)(27,35)
|
||||||
JaiDeclNamesImpl(DECL_NAMES)(27,28)
|
JaiDeclNamesImpl(DECL_NAMES)(27,28)
|
||||||
PsiElement(Jai:IDENT)('c')(27,28)
|
JaiDeclNameImpl(DECL_NAME)(27,28)
|
||||||
|
PsiElement(Jai:IDENT)('c')(27,28)
|
||||||
PsiElement(Jai:::)('::')(29,31)
|
PsiElement(Jai:::)('::')(29,31)
|
||||||
JaiInitializerImpl(INITIALIZER)(32,34)
|
JaiInitializerImpl(INITIALIZER)(32,34)
|
||||||
JaiLiteralExprImpl(LITERAL_EXPR)(32,34)
|
JaiLiteralExprImpl(LITERAL_EXPR)(32,34)
|
||||||
|
|||||||
Reference in New Issue
Block a user