Esempio n. 1
0
  private NodeList<Stmt> parseStatementsFor(
      String symbol, GExpansion expansion, NodeList<FormalParameter> hintParams, boolean optional) {
    NodeList<Stmt> stmts = emptyList();
    switch (expansion.kind) {
      case Sequence:
        stmts = stmts.appendAll(parseStatementsForChildren(symbol, expansion, hintParams, false));
        break;
      case ZeroOrOne:
        {
          if (expansion.children.size() == 1
              && expansion.children.get(0).kind == GExpansion.Kind.Choice) {
            stmts =
                stmts.appendAll(parseStatementsForChildren(symbol, expansion, hintParams, true));
          } else {
            stmts =
                stmts.append(
                    ifStmt(
                        matchCondition(
                            symbol,
                            expansion,
                            hintParams,
                            hintParams.map(p -> p.id().get().name())),
                        blockStmt()
                            .withStmts(
                                parseStatementsForChildren(symbol, expansion, hintParams, false))));
          }
          break;
        }
      case ZeroOrMore:
        {
          stmts =
              stmts.append(
                  whileStmt(
                      matchCondition(
                          symbol, expansion, hintParams, hintParams.map(p -> p.id().get().name())),
                      blockStmt()
                          .withStmts(
                              parseStatementsForChildren(symbol, expansion, hintParams, false))));
          break;
        }
      case OneOrMore:
        {
          stmts =
              stmts.append(
                  doStmt(
                      blockStmt()
                          .withStmts(
                              parseStatementsForChildren(symbol, expansion, hintParams, false)),
                      matchCondition(
                          symbol,
                          expansion,
                          hintParams,
                          hintParams.map(p -> p.id().get().name()))));
          break;
        }
      case Choice:
        {
          List<IfStmt> expansionsIfStmt =
              expansion
                  .children
                  .stream()
                  .map(
                      e ->
                          ifStmt(
                              matchCondition(
                                  symbol, e, hintParams, hintParams.map(p -> p.id().get().name())),
                              blockStmt()
                                  .withStmts(parseStatementsFor(symbol, e, hintParams, false))))
                  .collect(Collectors.toList());
          Collections.reverse(expansionsIfStmt);

          stmts =
              stmts.append(
                  listOf(expansionsIfStmt)
                      .foldRight(
                          (Stmt)
                              (optional
                                  ? null
                                  : blockStmt()
                                      .withStmts(
                                          listOf(
                                              throwStmt(
                                                  methodInvocationExpr(
                                                          name("produceParseException"))
                                                      .withArgs(
                                                          listOf(
                                                              firstTerminalsOf(expansion)
                                                                  .stream()
                                                                  .map(this::prefixedConstant)
                                                                  .collect(
                                                                      Collectors.toList()))))))),
                          (ifThenClause, elseClause) ->
                              optional && elseClause == null
                                  ? ifThenClause
                                  : ifThenClause.withElseStmt(elseClause)));
          break;
        }
      case NonTerminal:
        {
          Expr call =
              methodInvocationExpr(name("parse" + upperCaseFirst(expansion.symbol)))
                  .withArgs(expansion.hints.appendAll(expansion.arguments));
          stmts =
              stmts.append(
                  expressionStmt(
                      expansion.name == null
                          ? call
                          : assignExpr(name(expansion.name), AssignOp.Normal, call)));
          break;
        }
      case Terminal:
        {
          Expr argument = prefixedConstant(expansion.symbol);
          Expr call = methodInvocationExpr(name("parse")).withArgs(listOf(argument));
          stmts =
              stmts.append(
                  expressionStmt(
                      expansion.name == null
                          ? call
                          : assignExpr(name(expansion.name), AssignOp.Normal, call)));
          break;
        }
      case Action:
        {
          stmts = stmts.appendAll(expansion.action);
          break;
        }
      default:
    }
    return stmts;
  }