/* * 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; import java.util.ArrayList; import java.util.HashSet; /** * The Grammar checker object can be used to check certain properties of grammar * objects. * * @author Ryan Cavalcante */ public class GrammarChecker { /** * Creates an instance of GrammarChecker. */ public GrammarChecker() { } /** * Returns true if grammar is a regular grammar (i.e. if it * is either a right or left linear grammar). * * @param grammar * the grammar. * @return true if grammar is a regular grammar. */ public static boolean isRegularGrammar(Grammar grammar) { if (isRightLinearGrammar(grammar) || isLeftLinearGrammar(grammar)) return true; return false; } /** * Returns true if grammar is a right-linear grammar (i.e. * all productions are of the form A->xB or A->x). * * @param grammar * the grammar. * @return true if grammar is a right-linear grammar. */ public static boolean isRightLinearGrammar(Grammar grammar) { ProductionChecker pc = new ProductionChecker(); Production[] productions = grammar.getProductions(); for (int k = 0; k < productions.length; k++) { if (!ProductionChecker.isRightLinear(productions[k])) return false; } return true; } /** * Returns true if grammar is a left-linear grammar (i.e. all * productions are of the form A->Bx or A->x). * * @param grammar * the grammar. * @return true if grammar is a left-linear grammar. */ public static boolean isLeftLinearGrammar(Grammar grammar) { ProductionChecker pc = new ProductionChecker(); Production[] productions = grammar.getProductions(); for (int k = 0; k < productions.length; k++) { if (!ProductionChecker.isLeftLinear(productions[k])) return false; } return true; } /** * Returns true if grammar is a context-free grammar (i.e. * all productions are of the form A->x). * * @param grammar * the grammar. * @return true if grammar is a context-free grammar. */ public static boolean isContextFreeGrammar(Grammar grammar) { ProductionChecker pc = new ProductionChecker(); Production[] productions = grammar.getProductions(); for (int k = 0; k < productions.length; k++) { if (!ProductionChecker.isRestrictedOnLHS(productions[k])) return false; } return true; } /** * Returns true if variable is in any production, either on * the right or left hand side of the production, of grammar. * * @param variable * the variable. * @return true if variable is in any production of grammar. */ public static boolean isVariableInProductions(Grammar grammar, String variable) { ProductionChecker pc = new ProductionChecker(); Production[] productions = grammar.getProductions(); for (int k = 0; k < productions.length; k++) { if (ProductionChecker.isVariableInProduction(variable, productions[k])) { return true; } } return false; } /** * Returns true if terminal is in any production, either on * the right or left hand side of the production, of grammar. * * @param terminal * the terminal. * @return true if terminal is in any production in grammar. */ public static boolean isTerminalInProductions(Grammar grammar, String terminal) { ProductionChecker pc = new ProductionChecker(); Production[] productions = grammar.getProductions(); for (int k = 0; k < productions.length; k++) { if (ProductionChecker.isTerminalInProduction(terminal, productions[k])) { return true; } } return false; } /** * Returns all productions in grammar whose lhs is variable. * * @param variable * the variable * @param grammar * the grammar * @return all productions in grammar whose lhs is variable. */ public static Production[] getProductionsOnVariable(String variable, Grammar grammar) { ArrayList list = new ArrayList(); ProductionChecker pc = new ProductionChecker(); Production[] productions = grammar.getProductions(); for (int k = 0; k < productions.length; k++) { if (variable.equals(productions[k].getLHS())) { list.add(productions[k]); } } return (Production[]) list.toArray(new Production[0]); } /** * Returns all productions in grammar that have variable * as the only character on the left hand side and that are not unit * productions. * * @param variable * the variable * @param grammar * the grammar * @return all productions in grammar that have variable * as the only character on the left hand side and are not unit * productions. */ public static Production[] getNonUnitProductionsOnVariable(String variable, Grammar grammar) { ArrayList list = new ArrayList(); ProductionChecker pc = new ProductionChecker(); Production[] productions = grammar.getProductions(); for (int k = 0; k < productions.length; k++) { if (variable.equals(productions[k].getLHS()) && !ProductionChecker.isUnitProduction(productions[k])) { list.add(productions[k]); } } return (Production[]) list.toArray(new Production[0]); } /** * Returns true if production, or an identical production, * is already in grammar. * * @param production * the production * @param grammar * the grammar * @return true if production, or an identical production, * is already in grammar. */ public static boolean isProductionInGrammar(Production production, Grammar grammar) { Production[] productions = grammar.getProductions(); for (int k = 0; k < productions.length; k++) { if (production.equals(productions[k])) return true; } return false; } /** * Returns all productions in grammar that have variable * in them, either on the rhs or lhs. * * @param variable * the variable * @param grammar * the grammar * @return all productions in grammar that have variable * in them, either on the rhs or lhs. */ public static Production[] getProductionsWithVariable(String variable, Grammar grammar) { ArrayList list = new ArrayList(); ProductionChecker pc = new ProductionChecker(); Production[] productions = grammar.getProductions(); for (int k = 0; k < productions.length; k++) { if (ProductionChecker.isVariableInProduction(variable, productions[k])) { list.add(productions[k]); } } return (Production[]) list.toArray(new Production[0]); } /** * Returns all productions in grammar that have variable * on the right hand side. * * @param variable * the variable * @param grammar * the grammar * @return all productions in grammar that have variable * on the right hand side. */ public static Production[] getProductionsWithVariableOnRHS(String variable, Grammar grammar) { ProductionChecker pc = new ProductionChecker(); ArrayList list = new ArrayList(); Production[] productions = grammar.getProductions(); for (int k = 0; k < productions.length; k++) { if (ProductionChecker.isVariableOnRHS(productions[k], variable)) list.add(productions[k]); } return (Production[]) list.toArray(new Production[0]); } /** * Returns a list of those variables which are unresolved, i.e., which * appears in the right hand side but do not appear in the left hand side. * * @param grammar * the grammar to check * @return an array of the unresolved variables */ public static String[] getUnresolvedVariables(Grammar grammar) { String[] variables = grammar.getVariables(); HashSet variableSet = new HashSet(); for (int i = 0; i < variables.length; i++) variableSet.add(variables[i]); Production[] productions = grammar.getProductions(); for (int i = 0; i < productions.length; i++) { String[] lhsVariables = productions[i].getVariablesOnLHS(); for (int j = 0; j < lhsVariables.length; j++) variableSet.remove(lhsVariables[j]); } return (String[]) variableSet.toArray(new String[0]); } }