/*
* 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;
}
}