/* * JFLAP - Formal Languages and Automata Package * * * Susan H. Rodger * Computer Science Department * Duke University * August 27, 2009 * Copyright (c) 2002-2009 * All rights reserved. * JFLAP is open source software. Please see the LICENSE for terms. * */ package grammar; /** * The Production checker object can be used to check certain properties of * production objects. * * @author Ryan Cavalcante */ public class ProductionChecker { /** * Creates an instance of ProductionChecker. */ public ProductionChecker() { } /** * Returns true if production is linear (i.e. either right or * left linear). * * @param production * the production * @return true if production is linear. */ public static boolean isLinear(Production production) { if (isRightLinear(production) || isLeftLinear(production)) { return true; } return false; } /** * Returns true if production is right linear. * * @param production * the production. * @return true if production is right linear. */ public static boolean isRightLinear(Production production) { if (isRightLinearProductionWithVariable(production) || isLinearProductionWithNoVariable(production)) return true; return false; } /** * Returns true if production is left linear. * * @param production * the production. * @return true if production is left linear. */ public static boolean isLeftLinear(Production production) { if (isLeftLinearProductionWithVariable(production) || isLinearProductionWithNoVariable(production)) return true; return false; } /** * Returns true if production is a production of the form * A->Bx where x is a series of 0 or more terminals * * @param production * the production * @return true if production is a production of the form * A->Bx where x is a series of 0 or more terminals */ public static boolean isLeftLinearProductionWithVariable( Production production) { if (!isRestrictedOnLHS(production)) return false; String rhs = production.getRHS(); /** * if only one variable on rhs and it is first char on rhs. */ String[] variables = production.getVariablesOnRHS(); if (variables.length == 1) { char ch = rhs.charAt(0); if (isVariable(ch)) { return true; } } return false; } /** * Returns true if production is a production of the form * A->xB where x is a series of 0 or more terminals * * @param production * the production * @return true if production is a production of the form * A->xB where x is a series of 0 or more terminals */ public static boolean isRightLinearProductionWithVariable( Production production) { if (!isRestrictedOnLHS(production)) return false; String rhs = production.getRHS(); /** * if only one variable on rhs and it is last char on rhs. */ String[] variables = production.getVariablesOnRHS(); if (variables.length == 1) { char ch = rhs.charAt(rhs.length() - 1); if (isVariable(ch)) { return true; } } return false; } /** * Returns true if production is a production of the form * A->x where x is a series of 0 or more terminals. * * @param production * the production * @return true if production is a production of the form * A->x where x is a series of 0 or more terminals. */ public static boolean isLinearProductionWithNoVariable(Production production) { if (!isRestrictedOnLHS(production)) return false; String rhs = production.getRHS(); /** if rhs is all terminals. */ String[] terminals = production.getTerminalsOnRHS(); if (rhs.length() == terminals.length) return true; return false; } /** * Returns true if production is a unit production. * * @param production * the production. * @return true if production is a unit production. */ public static boolean isUnitProduction(Production production) { if (!isRestrictedOnLHS(production)) return false; String rhs = production.getRHS(); String[] variablesOnRHS = production.getVariablesOnRHS(); if (rhs.length() == 1 && variablesOnRHS.length == 1) { return true; } return false; } /** * Returns true if production is a lambda production. * * @param production * the production. * @return true if production is a lambda production. */ public static boolean isLambdaProduction(Production production) { if (!isRestrictedOnLHS(production)) return false; String rhs = production.getRHS(); if (rhs.length() == 0) { return true; } return false; } /** * Returns true if the left hand side of production is a * single variable. * * @param production * the production. * @return true if the left hand side of production is a * single variable. */ public static boolean isRestrictedOnLHS(Production production) { String lhs = production.getLHS(); String[] variablesOnLHS = production.getVariablesOnLHS(); if (lhs.length() == 1 && variablesOnLHS.length == 1) { return true; } return false; } /** * Returns true if variable is in the production, either on * the right or left hand side of the production. * * @param variable * the variable. * @param production * the production. * @return true if variable is in the production. */ public static boolean isVariableInProduction(String variable, Production production) { String[] variables = production.getVariables(); for (int k = 0; k < variables.length; k++) { if (variables[k].equals(variable)) return true; } return false; } /** * Returns true if terminal is in the production, either on * the right or left hand side of the production. * * @param terminal * the terminal. * @param production * the production. * @return true if terminal is in the production. */ public static boolean isTerminalInProduction(String terminal, Production production) { String[] terminals = production.getTerminals(); for (int k = 0; k < terminals.length; k++) { if (terminals[k].equals(terminal)) return true; } return false; } /** * Returns true if there are 1 or more terminals on the rhs of productions. * * @param production * the production * @return true if there are 1 or more terminals on the rhs of productions. */ public static boolean areTerminalsOnRHS(Production production) { String rhs = production.getRHS(); for (int k = 0; k < rhs.length(); k++) { char ch = rhs.charAt(k); if (isTerminal(ch)) return true; } return false; } /** * Returns true if ch is a variable. A variable is determined * to be any uppercase character. * * @param ch * the character being checked. * @return true if ch is a variable. */ public static boolean isVariable(char ch) { return Character.isUpperCase(ch); } /** * Returns true if ch is a terminal. A terminal is determined * to be any lowercase character. * * @param ch * the character being checked. * @return true if ch is a terminal. */ public static boolean isTerminal(char ch) { return !isVariable(ch); } /** * Returns true if variable is on the right hand side of * production. * * @param production * the production * @param variable * the variable * @return true if variable is on the right hand side of * production. */ public static boolean isVariableOnRHS(Production production, String variable) { String[] variables = production.getVariablesOnRHS(); for (int k = 0; k < variables.length; k++) { if (variables[k].equals(variable)) return true; } return false; } }