// This is a generated file. Not intended for manual editing.
package com.intellij.sh.parser;

import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiBuilder.Marker;
import static com.intellij.sh.ShTypes.*;
import static com.intellij.sh.parser.ShParserUtil.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.lang.ASTNode;
import com.intellij.psi.tree.TokenSet;
import com.intellij.lang.PsiParser;
import com.intellij.lang.LightPsiParser;

@SuppressWarnings({"SimplifiableIfStatement", "UnusedAssignment"})
public class ShParser implements PsiParser, LightPsiParser {

  public ASTNode parse(IElementType t, PsiBuilder b) {
    parseLight(t, b);
    return b.getTreeBuilt();
  }

  public void parseLight(IElementType t, PsiBuilder b) {
    boolean r;
    b = adapt_builder_(t, b, this, EXTENDS_SETS_);
    Marker m = enter_section_(b, 0, _COLLAPSE_, null);
    r = parse_root_(t, b);
    exit_section_(b, 0, m, t, r, true, TRUE_CONDITION);
  }

  protected boolean parse_root_(IElementType t, PsiBuilder b) {
    return parse_root_(t, b, 0);
  }

  static boolean parse_root_(IElementType t, PsiBuilder b, int l) {
    boolean r;
    if (t == BLOCK) {
      r = block(b, l + 1);
    }
    else if (t == DO_BLOCK) {
      r = do_block(b, l + 1);
    }
    else if (t == PARENTHESES_BLOCK) {
      r = parentheses_block(b, l + 1);
    }
    else {
      r = file(b, l + 1);
    }
    return r;
  }

  public static final TokenSet[] EXTENDS_SETS_ = new TokenSet[] {
    create_token_set_(ARITHMETIC_EXPANSION, OLD_ARITHMETIC_EXPANSION),
    create_token_set_(LITERAL, NUMBER, SIMPLE_COMMAND_ELEMENT, STRING,
      VARIABLE),
    create_token_set_(ASSIGNMENT_CONDITION, COMPARISON_CONDITION, CONDITION, EQUALITY_CONDITION,
      LITERAL_CONDITION, LOGICAL_AND_CONDITION, LOGICAL_BITWISE_CONDITION, LOGICAL_OR_CONDITION,
      PARENTHESES_CONDITION, REGEX_CONDITION),
    create_token_set_(ASSIGNMENT_COMMAND, CASE_COMMAND, COMMAND, COMMAND_SUBSTITUTION_COMMAND,
      CONDITIONAL_COMMAND, EVAL_COMMAND, FOR_COMMAND, FUNCTION_DEFINITION,
      GENERIC_COMMAND_DIRECTIVE, IF_COMMAND, INCLUDE_COMMAND, INCLUDE_DIRECTIVE,
      LET_COMMAND, PIPELINE_COMMAND, SELECT_COMMAND, SHELL_COMMAND,
      SIMPLE_COMMAND, SUBSHELL_COMMAND, TEST_COMMAND, UNTIL_COMMAND,
      WHILE_COMMAND),
    create_token_set_(ADD_EXPRESSION, ARRAY_EXPRESSION, ASSIGNMENT_EXPRESSION, BITWISE_AND_EXPRESSION,
      BITWISE_EXCLUSIVE_OR_EXPRESSION, BITWISE_OR_EXPRESSION, BITWISE_SHIFT_EXPRESSION, COMMA_EXPRESSION,
      COMPARISON_EXPRESSION, CONDITIONAL_EXPRESSION, EQUALITY_EXPRESSION, EXPRESSION,
      EXP_EXPRESSION, INDEX_EXPRESSION, LITERAL_EXPRESSION, LOGICAL_AND_EXPRESSION,
      LOGICAL_BITWISE_NEGATION_EXPRESSION, LOGICAL_OR_EXPRESSION, MUL_EXPRESSION, PARENTHESES_EXPRESSION,
      POST_EXPRESSION, PRE_EXPRESSION, UNARY_EXPRESSION),
    create_token_set_(ADD_OPERATION, ARRAY_OPERATION, ASSIGNMENT_OPERATION, BITWISE_AND_OPERATION,
      BITWISE_EXCLUSIVE_OR_OPERATION, BITWISE_OR_OPERATION, BITWISE_SHIFT_OPERATION, COMMA_OPERATION,
      COMPARISON_OPERATION, CONDITIONAL_OPERATION, EQUALITY_OPERATION, EXP_OPERATION,
      INDEX_OPERATION, LITERAL_OPERATION, LOGICAL_AND_OPERATION, LOGICAL_BITWISE_NEGATION_OPERATION,
      LOGICAL_OR_OPERATION, MUL_OPERATION, OPERATION, PARENTHESES_OPERATION,
      POST_OPERATION, PRE_OPERATION, UNARY_OPERATION),
  };

  /* ********************************************************** */
  // block | do_block
  static boolean any_block(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "any_block")) return false;
    if (!nextTokenIs(b, "", DO, LEFT_CURLY)) return false;
    boolean r;
    r = block(b, l + 1);
    if (!r) r = do_block(b, l + 1);
    return r;
  }

  /* ********************************************************** */
  // '(' ')'
  static boolean argument_list(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "argument_list")) return false;
    boolean r, p;
    Marker m = enter_section_(b, l, _NONE_);
    r = consumeTokens(b, 1, LEFT_PAREN, RIGHT_PAREN);
    p = r; // pin = 1
    exit_section_(b, l, m, r, p, ShParser::argument_list_recover);
    return r || p;
  }

  /* ********************************************************** */
  // !('\n'| '{' | '(')
  static boolean argument_list_recover(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "argument_list_recover")) return false;
    boolean r;
    Marker m = enter_section_(b, l, _NOT_);
    r = !argument_list_recover_0(b, l + 1);
    exit_section_(b, l, m, r, false, null);
    return r;
  }

  // '\n'| '{' | '('
  private static boolean argument_list_recover_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "argument_list_recover_0")) return false;
    boolean r;
    r = consumeToken(b, LINEFEED);
    if (!r) r = consumeToken(b, LEFT_CURLY);
    if (!r) r = consumeToken(b, LEFT_PAREN);
    return r;
  }

  /* ********************************************************** */
  // '((' expression? '))'
  public static boolean arithmetic_expansion(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "arithmetic_expansion")) return false;
    boolean r;
    Marker m = enter_section_(b, l, _NONE_, ARITHMETIC_EXPANSION, "<arithmetic expansion>");
    r = consumeToken(b, "((");
    r = r && arithmetic_expansion_1(b, l + 1);
    r = r && consumeToken(b, "))");
    exit_section_(b, l, m, r, false, null);
    return r;
  }

  // expression?
  private static boolean arithmetic_expansion_1(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "arithmetic_expansion_1")) return false;
    expression(b, l + 1, -1);
    return true;
  }

  /* ********************************************************** */
  // '(''(' arithmetic_for_expression ')'')' list_terminator? newlines
  static boolean arithmetic_for_clause(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "arithmetic_for_clause")) return false;
    if (!nextTokenIs(b, LEFT_PAREN)) return false;
    boolean r, p;
    Marker m = enter_section_(b, l, _NONE_);
    r = consumeTokens(b, 1, LEFT_PAREN, LEFT_PAREN);
    p = r; // pin = 1
    r = r && report_error_(b, arithmetic_for_expression(b, l + 1));
    r = p && report_error_(b, consumeTokens(b, -1, RIGHT_PAREN, RIGHT_PAREN)) && r;
    r = p && report_error_(b, arithmetic_for_clause_5(b, l + 1)) && r;
    r = p && newlines(b, l + 1) && r;
    exit_section_(b, l, m, r, p, null);
    return r || p;
  }

  // list_terminator?
  private static boolean arithmetic_for_clause_5(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "arithmetic_for_clause_5")) return false;
    list_terminator(b, l + 1);
    return true;
  }

  /* ********************************************************** */
  // expression? ';' newlines expression? ';' newlines expression?
  static boolean arithmetic_for_expression(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "arithmetic_for_expression")) return false;
    boolean r;
    Marker m = enter_section_(b, l, _NONE_);
    r = arithmetic_for_expression_0(b, l + 1);
    r = r && consumeToken(b, SEMI);
    r = r && newlines(b, l + 1);
    r = r && arithmetic_for_expression_3(b, l + 1);
    r = r && consumeToken(b, SEMI);
    r = r && newlines(b, l + 1);
    r = r && arithmetic_for_expression_6(b, l + 1);
    exit_section_(b, l, m, r, false, ShParser::arithmetic_for_expression_recover);
    return r;
  }

  // expression?
  private static boolean arithmetic_for_expression_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "arithmetic_for_expression_0")) return false;
    expression(b, l + 1, -1);
    return true;
  }

  // expression?
  private static boolean arithmetic_for_expression_3(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "arithmetic_for_expression_3")) return false;
    expression(b, l + 1, -1);
    return true;
  }

  // expression?
  private static boolean arithmetic_for_expression_6(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "arithmetic_for_expression_6")) return false;
    expression(b, l + 1, -1);
    return true;
  }

  /* ********************************************************** */
  // !(')'')')
  static boolean arithmetic_for_expression_recover(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "arithmetic_for_expression_recover")) return false;
    boolean r;
    Marker m = enter_section_(b, l, _NOT_);
    r = !arithmetic_for_expression_recover_0(b, l + 1);
    exit_section_(b, l, m, r, false, null);
    return r;
  }

  // ')'')'
  private static boolean arithmetic_for_expression_recover_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "arithmetic_for_expression_recover_0")) return false;
    boolean r;
    Marker m = enter_section_(b);
    r = consumeTokens(b, 0, RIGHT_PAREN, RIGHT_PAREN);
    exit_section_(b, m, null, r);
    return r;
  }

  /* ********************************************************** */
  // newlines '='? operation newlines
  public static boolean array_assignment(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "array_assignment")) return false;
    boolean r;
    Marker m = enter_section_(b, l, _NONE_, ARRAY_ASSIGNMENT, "<array assignment>");
    r = newlines(b, l + 1);
    r = r && array_assignment_1(b, l + 1);
    r = r && operation(b, l + 1, -1);
    r = r && newlines(b, l + 1);
    exit_section_(b, l, m, r, false, null);
    return r;
  }

  // '='?
  private static boolean array_assignment_1(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "array_assignment_1")) return false;
    consumeToken(b, ASSIGN);
    return true;
  }

  /* ********************************************************** */
  // array_expression? ('='|"+=") [assignment_list | <<parseUntilSpace (literal | composed_var)>>]
  //                             {'=' <<parseUntilSpace literal >>}*
  public static boolean assignment_command(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "assignment_command")) return false;
    boolean r;
    Marker m = enter_section_(b, l, _LEFT_, ASSIGNMENT_COMMAND, "<assignment command>");
    r = assignment_command_0(b, l + 1);
    r = r && assignment_command_1(b, l + 1);
    r = r && assignment_command_2(b, l + 1);
    r = r && assignment_command_3(b, l + 1);
    exit_section_(b, l, m, r, false, null);
    return r;
  }

  // array_expression?
  private static boolean assignment_command_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "assignment_command_0")) return false;
    array_expression(b, l + 1);
    return true;
  }

  // '='|"+="
  private static boolean assignment_command_1(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "assignment_command_1")) return false;
    boolean r;
    r = consumeToken(b, ASSIGN);
    if (!r) r = consumeToken(b, PLUS_ASSIGN);
    return r;
  }

  // [assignment_list | <<parseUntilSpace (literal | composed_var)>>]
  private static boolean assignment_command_2(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "assignment_command_2")) return false;
    assignment_command_2_0(b, l + 1);
    return true;
  }

  // assignment_list | <<parseUntilSpace (literal | composed_var)>>
  private static boolean assignment_command_2_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "assignment_command_2_0")) return false;
    boolean r;
    Marker m = enter_section_(b);
    r = assignment_list(b, l + 1);
    if (!r) r = parseUntilSpace(b, l + 1, ShParser::assignment_command_2_0_1_0);
    exit_section_(b, m, null, r);
    return r;
  }

  // literal | composed_var
  private static boolean assignment_command_2_0_1_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "assignment_command_2_0_1_0")) return false;
    boolean r;
    r = literal(b, l + 1);
    if (!r) r = composed_var(b, l + 1);
    return r;
  }

  // {'=' <<parseUntilSpace literal >>}*
  private static boolean assignment_command_3(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "assignment_command_3")) return false;
    while (true) {
      int c = current_position_(b);
      if (!assignment_command_3_0(b, l + 1)) break;
      if (!empty_element_parsed_guard_(b, "assignment_command_3", c)) break;
    }
    return true;
  }

  // '=' <<parseUntilSpace literal >>
  private static boolean assignment_command_3_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "assignment_command_3_0")) return false;
    boolean r;
    Marker m = enter_section_(b);
    r = consumeToken(b, ASSIGN);
    r = r && parseUntilSpace(b, l + 1, ShParser::literal);
    exit_section_(b, m, null, r);
    return r;
  }

  /* ********************************************************** */
  // '(' (<<backslash>> | array_assignment)* ')'
  public static boolean assignment_list(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "assignment_list")) return false;
    if (!nextTokenIs(b, LEFT_PAREN)) return false;
    boolean r, p;
    Marker m = enter_section_(b, l, _NONE_, ASSIGNMENT_LIST, null);
    r = consumeToken(b, LEFT_PAREN);
    p = r; // pin = 1
    r = r && report_error_(b, assignment_list_1(b, l + 1));
    r = p && consumeToken(b, RIGHT_PAREN) && r;
    exit_section_(b, l, m, r, p, null);
    return r || p;
  }

  // (<<backslash>> | array_assignment)*
  private static boolean assignment_list_1(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "assignment_list_1")) return false;
    while (true) {
      int c = current_position_(b);
      if (!assignment_list_1_0(b, l + 1)) break;
      if (!empty_element_parsed_guard_(b, "assignment_list_1", c)) break;
    }
    return true;
  }

  // <<backslash>> | array_assignment
  private static boolean assignment_list_1_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "assignment_list_1_0")) return false;
    boolean r;
    Marker m = enter_section_(b);
    r = backslash(b, l + 1);
    if (!r) r = array_assignment(b, l + 1);
    exit_section_(b, m, null, r);
    return r;
  }

  /* ********************************************************** */
  // '{' block_compound_list '}'
  public static boolean block(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "block")) return false;
    if (!nextTokenIs(b, LEFT_CURLY)) return false;
    boolean r, p;
    Marker m = enter_section_(b, l, _NONE_, BLOCK, null);
    r = consumeToken(b, LEFT_CURLY);
    p = r; // pin = 1
    r = r && report_error_(b, block_compound_list(b, l + 1));
    r = p && consumeToken(b, RIGHT_CURLY) && r;
    exit_section_(b, l, m, r, p, null);
    return r || p;
  }

  /* ********************************************************** */
  // newlines ((pipeline_command_list | pipeline_command) end_of_list newlines)+
  public static boolean block_compound_list(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "block_compound_list")) return false;
    boolean r, p;
    Marker m = enter_section_(b, l, _NONE_, COMPOUND_LIST, "<block compound list>");
    r = newlines(b, l + 1);
    p = r; // pin = 1
    r = r && block_compound_list_1(b, l + 1);
    exit_section_(b, l, m, r, p, ShParser::block_compound_list_recover);
    return r || p;
  }

  // ((pipeline_command_list | pipeline_command) end_of_list newlines)+
  private static boolean block_compound_list_1(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "block_compound_list_1")) return false;
    boolean r;
    Marker m = enter_section_(b);
    r = block_compound_list_1_0(b, l + 1);
    while (r) {
      int c = current_position_(b);
      if (!block_compound_list_1_0(b, l + 1)) break;
      if (!empty_element_parsed_guard_(b, "block_compound_list_1", c)) break;
    }
    exit_section_(b, m, null, r);
    return r;
  }

  // (pipeline_command_list | pipeline_command) end_of_list newlines
  private static boolean block_compound_list_1_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "block_compound_list_1_0")) return false;
    boolean r, p;
    Marker m = enter_section_(b, l, _NONE_);
    r = block_compound_list_1_0_0(b, l + 1);
    p = r; // pin = 1
    r = r && report_error_(b, end_of_list(b, l + 1));
    r = p && newlines(b, l + 1) && r;
    exit_section_(b, l, m, r, p, null);
    return r || p;
  }

  // pipeline_command_list | pipeline_command
  private static boolean block_compound_list_1_0_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "block_compound_list_1_0_0")) return false;
    boolean r;
    Marker m = enter_section_(b);
    r = pipeline_command_list(b, l + 1);
    if (!r) r = pipeline_command(b, l + 1);
    exit_section_(b, m, null, r);
    return r;
  }

  /* ********************************************************** */
  // !('{' | '\n' | '}' | do | done | '(' | ')')
  static boolean block_compound_list_recover(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "block_compound_list_recover")) return false;
    boolean r;
    Marker m = enter_section_(b, l, _NOT_);
    r = !block_compound_list_recover_0(b, l + 1);
    exit_section_(b, l, m, r, false, null);
    return r;
  }

  // '{' | '\n' | '}' | do | done | '(' | ')'
  private static boolean block_compound_list_recover_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "block_compound_list_recover_0")) return false;
    boolean r;
    r = consumeToken(b, LEFT_CURLY);
    if (!r) r = consumeToken(b, LINEFEED);
    if (!r) r = consumeToken(b, RIGHT_CURLY);
    if (!r) r = consumeToken(b, DO);
    if (!r) r = consumeToken(b, DONE);
    if (!r) r = consumeToken(b, LEFT_PAREN);
    if (!r) r = consumeToken(b, RIGHT_PAREN);
    return r;
  }

  /* ********************************************************** */
  // '{' (word | brace_expansion)* '}'
  public static boolean brace_expansion(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "brace_expansion")) return false;
    if (!nextTokenIs(b, LEFT_CURLY)) return false;
    boolean r;
    Marker m = enter_section_(b);
    r = consumeToken(b, LEFT_CURLY);
    r = r && brace_expansion_1(b, l + 1);
    r = r && consumeToken(b, RIGHT_CURLY);
    exit_section_(b, m, BRACE_EXPANSION, r);
    return r;
  }

  // (word | brace_expansion)*
  private static boolean brace_expansion_1(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "brace_expansion_1")) return false;
    while (true) {
      int c = current_position_(b);
      if (!brace_expansion_1_0(b, l + 1)) break;
      if (!empty_element_parsed_guard_(b, "brace_expansion_1", c)) break;
    }
    return true;
  }

  // word | brace_expansion
  private static boolean brace_expansion_1_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "brace_expansion_1_0")) return false;
    boolean r;
    r = consumeToken(b, WORD);
    if (!r) r = brace_expansion(b, l + 1);
    return r;
  }

  /* ********************************************************** */
  // newlines pattern ')' newlines compound_case_list?
  public static boolean case_clause(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "case_clause")) return false;
    boolean r, p;
    Marker m = enter_section_(b, l, _NONE_, CASE_CLAUSE, "<case clause>");
    r = newlines(b, l + 1);
    r = r && pattern(b, l + 1);
    r = r && consumeToken(b, RIGHT_PAREN);
    p = r; // pin = 3
    r = r && report_error_(b, newlines(b, l + 1));
    r = p && case_clause_4(b, l + 1) && r;
    exit_section_(b, l, m, r, p, null);
    return r || p;
  }

  // compound_case_list?
  private static boolean case_clause_4(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "case_clause_4")) return false;
    compound_case_list(b, l + 1);
    return true;
  }

  /* ********************************************************** */
  // case_clause (';;' (case_clause | newlines))*
  static boolean case_clause_list(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "case_clause_list")) return false;
    boolean r, p;
    Marker m = enter_section_(b, l, _NONE_);
    r = case_clause(b, l + 1);
    p = r; // pin = 1
    r = r && case_clause_list_1(b, l + 1);
    exit_section_(b, l, m, r, p, ShParser::case_clause_recover);
    return r || p;
  }

  // (';;' (case_clause | newlines))*
  private static boolean case_clause_list_1(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "case_clause_list_1")) return false;
    while (true) {
      int c = current_position_(b);
      if (!case_clause_list_1_0(b, l + 1)) break;
      if (!empty_element_parsed_guard_(b, "case_clause_list_1", c)) break;
    }
    return true;
  }

  // ';;' (case_clause | newlines)
  private static boolean case_clause_list_1_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "case_clause_list_1_0")) return false;
    boolean r, p;
    Marker m = enter_section_(b, l, _NONE_);
    r = consumeToken(b, CASE_END);
    p = r; // pin = 1
    r = r && case_clause_list_1_0_1(b, l + 1);
    exit_section_(b, l, m, r, p, null);
    return r || p;
  }

  // case_clause | newlines
  private static boolean case_clause_list_1_0_1(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "case_clause_list_1_0_1")) return false;
    boolean r;
    r = case_clause(b, l + 1);
    if (!r) r = newlines(b, l + 1);
    return r;
  }

  /* ********************************************************** */
  // !(esac)
  static boolean case_clause_recover(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "case_clause_recover")) return false;
    boolean r;
    Marker m = enter_section_(b, l, _NOT_);
    r = !consumeToken(b, ESAC);
    exit_section_(b, l, m, r, false, null);
    return r;
  }

  /* ********************************************************** */
  // case w+ in case_clause_list esac
  public static boolean case_command(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "case_command")) return false;
    if (!nextTokenIs(b, CASE)) return false;
    boolean r, p;
    Marker m = enter_section_(b, l, _NONE_, CASE_COMMAND, null);
    r = consumeToken(b, CASE);
    p = r; // pin = 1
    r = r && report_error_(b, case_command_1(b, l + 1));
    r = p && report_error_(b, consumeToken(b, IN)) && r;
    r = p && report_error_(b, case_clause_list(b, l + 1)) && r;
    r = p && consumeToken(b, ESAC) && r;
    exit_section_(b, l, m, r, p, null);
    return r || p;
  }

  // w+
  private static boolean case_command_1(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "case_command_1")) return false;
    boolean r;
    Marker m = enter_section_(b);
    r = w(b, l + 1);
    while (r) {
      int c = current_position_(b);
      if (!w(b, l + 1)) break;
      if (!empty_element_parsed_guard_(b, "case_command_1", c)) break;
    }
    exit_section_(b, m, null, r);
    return r;
  }

  /* ********************************************************** */
  // !(')'|';;'|esac)
  static boolean case_pattern_recover(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "case_pattern_recover")) return false;
    boolean r;
    Marker m = enter_section_(b, l, _NOT_);
    r = !case_pattern_recover_0(b, l + 1);
    exit_section_(b, l, m, r, false, null);
    return r;
  }

  // ')'|';;'|esac
  private static boolean case_pattern_recover_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "case_pattern_recover_0")) return false;
    boolean r;
    r = consumeToken(b, RIGHT_PAREN);
    if (!r) r = consumeToken(b, CASE_END);
    if (!r) r = consumeToken(b, ESAC);
    return r;
  }

  /* ********************************************************** */
  // shell_command [heredoc | redirection+]
  //           | include_command
  //           | simple_command
  public static boolean command(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "command")) return false;
    boolean r;
    Marker m = enter_section_(b, l, _COLLAPSE_, COMMAND, "<command>");
    r = command_0(b, l + 1);
    if (!r) r = include_command(b, l + 1);
    if (!r) r = simple_command(b, l + 1);
    exit_section_(b, l, m, r, false, null);
    return r;
  }

  // shell_command [heredoc | redirection+]
  private static boolean command_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "command_0")) return false;
    boolean r;
    Marker m = enter_section_(b);
    r = shell_command(b, l + 1);
    r = r && command_0_1(b, l + 1);
    exit_section_(b, m, null, r);
    return r;
  }

  // [heredoc | redirection+]
  private static boolean command_0_1(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "command_0_1")) return false;
    command_0_1_0(b, l + 1);
    return true;
  }

  // heredoc | redirection+
  private static boolean command_0_1_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "command_0_1_0")) return false;
    boolean r;
    Marker m = enter_section_(b);
    r = heredoc(b, l + 1);
    if (!r) r = command_0_1_0_1(b, l + 1);
    exit_section_(b, m, null, r);
    return r;
  }

  // redirection+
  private static boolean command_0_1_0_1(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "command_0_1_0_1")) return false;
    boolean r;
    Marker m = enter_section_(b);
    r = redirection(b, l + 1);
    while (r) {
      int c = current_position_(b);
      if (!redirection(b, l + 1)) break;
      if (!empty_element_parsed_guard_(b, "command_0_1_0_1", c)) break;
    }
    exit_section_(b, m, null, r);
    return r;
  }

  /* ********************************************************** */
  // !<<isModeOn "BACKQUOTE">> OPEN_BACKQUOTE <<withOn "BACKQUOTE" list?>> CLOSE_BACKQUOTE
  public static boolean command_substitution_command(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "command_substitution_command")) return false;
    boolean r, p;
    Marker m = enter_section_(b, l, _NONE_, COMMAND_SUBSTITUTION_COMMAND, "<command substitution command>");
    r = command_substitution_command_0(b, l + 1);
    r = r && consumeToken(b, OPEN_BACKQUOTE);
    p = r; // pin = 2
    r = r && report_error_(b, withOn(b, l + 1, "BACKQUOTE", ShParser::command_substitution_command_2_1));
    r = p && consumeToken(b, CLOSE_BACKQUOTE) && r;
    exit_section_(b, l, m, r, p, null);
    return r || p;
  }

  // !<<isModeOn "BACKQUOTE">>
  private static boolean command_substitution_command_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "command_substitution_command_0")) return false;
    boolean r;
    Marker m = enter_section_(b, l, _NOT_);
    r = !isModeOn(b, l + 1, "BACKQUOTE");
    exit_section_(b, l, m, r, false, null);
    return r;
  }

  // list?
  private static boolean command_substitution_command_2_1(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "command_substitution_command_2_1")) return false;
    list(b, l + 1);
    return true;
  }

  /* ********************************************************** */
  // pipeline_command (
  //                      ('|' | '|&' | '&&' | '||') newlines pipeline_command
  //                    | (';' | '&') pipeline_command?
  //                  )*
  public static boolean commands_list(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "commands_list")) return false;
    boolean r, p;
    Marker m = enter_section_(b, l, _NONE_, COMMANDS_LIST, "<commands list>");
    r = pipeline_command(b, l + 1);
    p = r; // pin = 1
    r = r && commands_list_1(b, l + 1);
    exit_section_(b, l, m, r, p, null);
    return r || p;
  }

  // (
  //                      ('|' | '|&' | '&&' | '||') newlines pipeline_command
  //                    | (';' | '&') pipeline_command?
  //                  )*
  private static boolean commands_list_1(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "commands_list_1")) return false;
    while (true) {
      int c = current_position_(b);
      if (!commands_list_1_0(b, l + 1)) break;
      if (!empty_element_parsed_guard_(b, "commands_list_1", c)) break;
    }
    return true;
  }

  // ('|' | '|&' | '&&' | '||') newlines pipeline_command
  //                    | (';' | '&') pipeline_command?
  private static boolean commands_list_1_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "commands_list_1_0")) return false;
    boolean r;
    Marker m = enter_section_(b);
    r = commands_list_1_0_0(b, l + 1);
    if (!r) r = commands_list_1_0_1(b, l + 1);
    exit_section_(b, m, null, r);
    return r;
  }

  // ('|' | '|&' | '&&' | '||') newlines pipeline_command
  private static boolean commands_list_1_0_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "commands_list_1_0_0")) return false;
    boolean r, p;
    Marker m = enter_section_(b, l, _NONE_);
    r = commands_list_1_0_0_0(b, l + 1);
    p = r; // pin = 1
    r = r && report_error_(b, newlines(b, l + 1));
    r = p && pipeline_command(b, l + 1) && r;
    exit_section_(b, l, m, r, p, null);
    return r || p;
  }

  // '|' | '|&' | '&&' | '||'
  private static boolean commands_list_1_0_0_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "commands_list_1_0_0_0")) return false;
    boolean r;
    r = consumeToken(b, PIPE);
    if (!r) r = consumeToken(b, PIPE_AMP);
    if (!r) r = consumeToken(b, AND_AND);
    if (!r) r = consumeToken(b, OR_OR);
    return r;
  }

  // (';' | '&') pipeline_command?
  private static boolean commands_list_1_0_1(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "commands_list_1_0_1")) return false;
    boolean r, p;
    Marker m = enter_section_(b, l, _NONE_);
    r = commands_list_1_0_1_0(b, l + 1);
    p = r; // pin = 1
    r = r && commands_list_1_0_1_1(b, l + 1);
    exit_section_(b, l, m, r, p, null);
    return r || p;
  }

  // ';' | '&'
  private static boolean commands_list_1_0_1_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "commands_list_1_0_1_0")) return false;
    boolean r;
    r = consumeToken(b, SEMI);
    if (!r) r = consumeToken(b, AMP);
    return r;
  }

  // pipeline_command?
  private static boolean commands_list_1_0_1_1(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "commands_list_1_0_1_1")) return false;
    pipeline_command(b, l + 1);
    return true;
  }

  /* ********************************************************** */
  // '$' &('(' | '{') composed_var_inner
  static boolean composed_var(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "composed_var")) return false;
    if (!nextTokenIs(b, DOLLAR)) return false;
    boolean r, p;
    Marker m = enter_section_(b, l, _NONE_);
    r = consumeToken(b, DOLLAR);
    r = r && composed_var_1(b, l + 1);
    p = r; // pin = 2
    r = r && composed_var_inner(b, l + 1);
    exit_section_(b, l, m, r, p, null);
    return r || p;
  }

  // &('(' | '{')
  private static boolean composed_var_1(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "composed_var_1")) return false;
    boolean r;
    Marker m = enter_section_(b, l, _AND_);
    r = composed_var_1_0(b, l + 1);
    exit_section_(b, l, m, r, false, null);
    return r;
  }

  // '(' | '{'
  private static boolean composed_var_1_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "composed_var_1_0")) return false;
    boolean r;
    r = consumeToken(b, LEFT_PAREN);
    if (!r) r = consumeToken(b, LEFT_CURLY);
    return r;
  }

  /* ********************************************************** */
  // arithmetic_expansion
  //                               | subshell_command
  //                               | shell_parameter_expansion
  static boolean composed_var_inner(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "composed_var_inner")) return false;
    boolean r;
    r = arithmetic_expansion(b, l + 1);
    if (!r) r = subshell_command(b, l + 1);
    if (!r) r = shell_parameter_expansion(b, l + 1);
    return r;
  }

  /* ********************************************************** */
  // ((pipeline_command_list | pipeline_command) end_of_list? newlines)+
  public static boolean compound_case_list(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "compound_case_list")) return false;
    boolean r;
    Marker m = enter_section_(b, l, _NONE_, COMPOUND_LIST, "<compound case list>");
    r = compound_case_list_0(b, l + 1);
    while (r) {
      int c = current_position_(b);
      if (!compound_case_list_0(b, l + 1)) break;
      if (!empty_element_parsed_guard_(b, "compound_case_list", c)) break;
    }
    exit_section_(b, l, m, r, false, null);
    return r;
  }

  // (pipeline_command_list | pipeline_command) end_of_list? newlines
  private static boolean compound_case_list_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "compound_case_list_0")) return false;
    boolean r, p;
    Marker m = enter_section_(b, l, _NONE_);
    r = compound_case_list_0_0(b, l + 1);
    p = r; // pin = 1
    r = r && report_error_(b, compound_case_list_0_1(b, l + 1));
    r = p && newlines(b, l + 1) && r;
    exit_section_(b, l, m, r, p, null);
    return r || p;
  }

  // pipeline_command_list | pipeline_command
  private static boolean compound_case_list_0_0(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "compound_case_list_0_0")) return false;
    boolean r;
    Marker m = enter_section_(b);
    r = pipeline_command_list(b, l + 1);
    if (!r) r = pipeline_command(b, l + 1);
    exit_section_(b, m, null, r);
    return r;
  }

  // end_of_list?
