All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jparsec.examples.java.parser.StatementParser Maven / Gradle / Ivy

The newest version!
/*****************************************************************************
 * Copyright (C) jparsec.org                                                *
 * ------------------------------------------------------------------------- *
 * Licensed under the Apache License, Version 2.0 (the "License");           *
 * you may not use this file except in compliance with the License.          *
 * You may obtain a copy of the License at                                   *
 *                                                                           *
 * http://www.apache.org/licenses/LICENSE-2.0                                *
 *                                                                           *
 * Unless required by applicable law or agreed to in writing, software       *
 * distributed under the License is distributed on an "AS IS" BASIS,         *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  *
 * See the License for the specific language governing permissions and       *
 * limitations under the License.                                            *
 *****************************************************************************/
package org.jparsec.examples.java.parser;

import static org.jparsec.Parsers.between;
import static org.jparsec.examples.java.parser.ExpressionParser.paren;
import static org.jparsec.examples.java.parser.TerminalParser.phrase;
import static org.jparsec.examples.java.parser.TerminalParser.term;

import java.util.ArrayList;
import java.util.List;
import java.util.function.UnaryOperator;

import org.jparsec.Parser;
import org.jparsec.Parsers;
import org.jparsec.Terminals;
import org.jparsec.examples.java.ast.expression.Expression;
import org.jparsec.examples.java.ast.statement.Annotation;
import org.jparsec.examples.java.ast.statement.AssertStatement;
import org.jparsec.examples.java.ast.statement.BlockStatement;
import org.jparsec.examples.java.ast.statement.BreakStatement;
import org.jparsec.examples.java.ast.statement.ContinueStatement;
import org.jparsec.examples.java.ast.statement.DoWhileStatement;
import org.jparsec.examples.java.ast.statement.ExpressionListStatement;
import org.jparsec.examples.java.ast.statement.ExpressionStatement;
import org.jparsec.examples.java.ast.statement.ForStatement;
import org.jparsec.examples.java.ast.statement.ForeachStatement;
import org.jparsec.examples.java.ast.statement.IfStatement;
import org.jparsec.examples.java.ast.statement.LabelStatement;
import org.jparsec.examples.java.ast.statement.Modifier;
import org.jparsec.examples.java.ast.statement.NopStatement;
import org.jparsec.examples.java.ast.statement.ParameterDef;
import org.jparsec.examples.java.ast.statement.ReturnStatement;
import org.jparsec.examples.java.ast.statement.Statement;
import org.jparsec.examples.java.ast.statement.SuperCallStatement;
import org.jparsec.examples.java.ast.statement.SwitchStatement;
import org.jparsec.examples.java.ast.statement.SynchronizedBlockStatement;
import org.jparsec.examples.java.ast.statement.SystemModifier;
import org.jparsec.examples.java.ast.statement.ThisCallStatement;
import org.jparsec.examples.java.ast.statement.ThrowStatement;
import org.jparsec.examples.java.ast.statement.TryStatement;
import org.jparsec.examples.java.ast.statement.VarStatement;
import org.jparsec.examples.java.ast.statement.WhileStatement;

/**
 * Parses a statement.
 * 
 * @author Ben Yu
 */
public final class StatementParser {
  
  static Parser systemModifier(SystemModifier... modifiers) {
    List> list = new ArrayList>(modifiers.length);
    for (Modifier modifier : modifiers) {
      list.add(term(modifier.toString()).retn(modifier));
    }
    return Parsers.or(list);
  }
  
  static final Parser SYSTEM_MODIFIER = systemModifier(SystemModifier.values());
  
  static Parser annotation(Parser expr) {
    Parser element = Parsers.sequence(
        Terminals.Identifier.PARSER.followedBy(term("=")).atomic().optional(),
        ExpressionParser.arrayInitializerOrRegularExpression(expr),
        Annotation.Element::new);
    return Parsers.sequence(
        term("@").next(TypeLiteralParser.ELEMENT_TYPE_LITERAL),
        paren(element.sepBy(term(","))).optional(),
        Annotation::new);
  }
  
  static Parser modifier(Parser expr) {
    return Parsers.or(annotation(expr), SYSTEM_MODIFIER);
  }
  
  static final Parser NOP = term(";").retn(NopStatement.instance);
  
  static final Parser> LABEL = Terminals.Identifier.PARSER
      .followedBy(term(":"))
      .atomic()
      .map(name -> stmt -> new LabelStatement(name, stmt));
  
  static final Parser BREAK =
      between(term("break"), Terminals.Identifier.PARSER.optional(), term(";"))
          .map(BreakStatement::new);
  
  static final Parser CONTINUE =
      between(term("continue"), Terminals.Identifier.PARSER.optional(), term(";"))
          .map(ContinueStatement::new);
  
  static Parser returnStatement(Parser expr) {
    return between(term("return"), expr.optional(), term(";")).map(ReturnStatement::new);
  }
  
  static Parser blockStatement(Parser stmt) {
    return between(term("{"), stmt.many(), term("}")).map(BlockStatement::new);
  }
  
  static Parser whileStatement(Parser expr, Parser stmt) {
    return Parsers.sequence(
        between(phrase("while ("), expr, term(")")), stmt,
        WhileStatement::new);
  }
  
  static Parser doWhileStatement(Parser stmt, Parser expr) {
    return Parsers.sequence(
        term("do").next(stmt),
        between(phrase("while ("),  expr, phrase(") ;")),
        DoWhileStatement::new);
  }
  
  static Parser ifStatement(Parser expr, Parser stmt) {
    return Parsers.sequence(
        between(phrase("if ("), expr, term(")")),
        stmt, 
        Parsers.pair(between(phrase("else if ("), expr, term(")")), stmt).many(),
        term("else").next(stmt).optional(),
        IfStatement::new);
  }
  
  static Parser switchStatement(Parser expr, Parser stmt) {
    return Parsers.sequence(
        between(phrase("switch ("), expr, phrase(") {")),
            Parsers.pair(between(term("case"), expr, term(":")), stmt.optional()).many(),
            phrase("default :").next(stmt.optional()).optional().followedBy(term("}")),
            SwitchStatement::new);
  }
  
  static Parser foreachStatement(Parser expr, Parser stmt) {
    return Parsers.sequence(
        phrase("for (").next(TypeLiteralParser.TYPE_LITERAL),
        Terminals.Identifier.PARSER,
        term(":").next(expr),
        term(")").next(stmt),
        ForeachStatement::new);
  }
  
  static Parser forStatement(Parser expr, Parser stmt) {
    return Parsers.sequence(
        phrase("for (").next(Parsers.or(varStatement(expr), expressionList(expr), NOP)),
        expr.optional(),
        between(term(";"), expr.sepBy(term(",")), term(")")),
        stmt,
        ForStatement::new);
  }
  
  static Parser thisCall(Parser expr) {
    return between(phrase("this ("), expr.sepBy(term(",")), phrase(") ;"))
        .map(ThisCallStatement::new);
  }
  
  static Parser superCall(Parser expr) {
    return between(phrase("super ("), expr.sepBy(term(",")), phrase(") ;"))
        .map(SuperCallStatement::new);
  }
  
  static Parser varStatement(Parser expr) {
    Parser initializer =
        term("=").next(ExpressionParser.arrayInitializerOrRegularExpression(expr));
    Parser var = Parsers.sequence(
        Terminals.Identifier.PARSER, initializer.optional(), VarStatement.Var::new);
    return Parsers.sequence(
        modifier(expr).many(),
        TypeLiteralParser.TYPE_LITERAL,
        var.sepBy1(term(",")).followedBy(term(";")),
        VarStatement::new);
  }

  static Parser expressionList(Parser expr) {
    return expr.sepBy1(term(",")).followedBy(term(";")).map(ExpressionListStatement::new);
  }
  
  static Parser synchronizedBlock(Parser stmt) {
    return term("synchronized").next(blockStatement(stmt)).map(SynchronizedBlockStatement::new);
  }
  
  static Parser assertStatement(Parser expr) {
    return Parsers.sequence(
        term("assert").next(expr), term(":").next(expr).optional().followedBy(term(";")),
        AssertStatement::new);
  }
  
  static Parser expression(Parser expr) {
    return expr.followedBy(term(";")).map(ExpressionStatement::new);
  }
  
  static Parser parameter(Parser mod) {
    return Parsers.sequence(
        mod.many(), TypeLiteralParser.TYPE_LITERAL, term("...").succeeds(), Terminals.Identifier.PARSER,
        ParameterDef::new);
  }
  
  static Parser tryStatement(Parser mod, Parser stmt) {
    Parser block = blockStatement(stmt);
    return Parsers.sequence(
        term("try").next(block),
        Parsers.sequence(
            term("catch").next(between(term("("), parameter(mod), term(")"))), block,
            TryStatement.CatchBlock::new).many(),
        term("finally").next(block).optional(),
        TryStatement::new);
  }
  
  static Parser throwStatement(Parser thrown) {
    return between(term("throw"), thrown, term(";")).map(ThrowStatement::new);
  }
  
  static Parser statement(Parser expr) {
    Parser.Reference ref = Parser.newReference();
    Parser lazy = ref.lazy();
    @SuppressWarnings("unchecked")
    Parser parser = Parsers.or(
        returnStatement(expr), BREAK, CONTINUE, blockStatement(lazy),
        foreachStatement(expr, lazy), forStatement(expr, lazy),
        whileStatement(expr, lazy), doWhileStatement(lazy, expr),
        ifStatement(expr, lazy), switchStatement(expr, lazy),
        tryStatement(modifier(expr), lazy), throwStatement(expr),
        synchronizedBlock(lazy), assertStatement(expr), varStatement(expr),
        thisCall(expr), superCall(expr),
        expression(expr), NOP).prefix(LABEL).label("statement");
    ref.set(parser);
    return parser;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy