Professional Documents
Culture Documents
Experiment No. 4b
Program 1
PROBLEM The problem is to develop a program that can parse a string using a given grammar and
STATEMENT : parsing table, and determine whether the string is accepted or rejected by the grammar.
The program must be able to accept the grammar and parsing table as inputs, and then
take a user-provided string as input for parsing. The program should then use the parsing
table to determine if the string can be generated by the grammar or not. The output of the
program should indicate whether the string is accepted or rejected by the grammar.
Step 1: First check for left recursion in the grammar, if there is left recursion in the
grammar remove that and go to step 2.
In the table, rows will contain the Non-Terminals and the column will contain the
Terminal Symbols. All the Null Productions of the Grammars will go under the Follow
elements and the remaining productions will lie under the elements of the First set.
import java.util.*;
class Production {
String LHS;
List<String> RHSList;
Production() {
RHSList = new ArrayList<>();
}
}
class Table {
List<String> sb;
Stack<String> stack;
Table() {
table = new HashMap<>();
stack = new Stack<>();
// Input window
///
//Input 1:
nonTerminals.add("S");
Terminals.add("(");
Terminals.add(")");
Terminals.add("$");
stack.push("$");
table.get("S").put("(", prod1);
table.get("S").put(")", prod2);
table.get("S").put("$", prod2);
// Input 2:
// nonTerminals.add("S");
// Terminals.add("(");
// Terminals.add(")");
// Terminals.add("$");
// //dont consider epsilon
// stack.push("$");
// table.get("S").put("(", prod1);
// table.get("S").put(")", prod2);
// table.get("S").put("$", prod2);
/////
}
System.out.print("[");
for(int i = 0; i <sb.size(); i++){
if(i==idx){
System.out.print("\u001B[35m"+sb.get(i)+"\u001B[0m ");
}else{
System.out.print("\u001B[0m"+sb.get(i)+"\u001B[0m ");
}
}
System.out.print("]\n");
void displayParsingTable() {
System.out.println("----------------------------------------------
------------------------------------");
System.out.println();
}
System.out.println("----------------------------------------------
------------------------------------");
}
void checkParsing() {
modifyString();
int index = 0;
System.out.print("Stack: ");
System.out.print("[");
Iterator<String> stkitr = stack.iterator();
while(stkitr.hasNext()){
System.out.print(stkitr.next()+" ");
}
System.out.print("]\n");
System.out.println("Stack TOP: \u001B[33m"+left+"\u001B[0m");
displaySampleString(index);
System.out.println("------------------------------------------
----------------------------------------");
// when the stack top symbol and the character on the pointer
is equal(same), pop the stack and increment the pointer
if (left.equals(right)) {
stack.pop();
index++;
continue;
}
stack.pop();
stack.push(rhsList.get(k));
}
} else {
// if its a null production
stack.pop();
}
}
}
void modifyString() {
sb = new ArrayList<>();
sb.add("(");
sb.add("(");
sb.add("(");
sb.add("(");
sb.add(")");
sb.add(")");
sb.add(")");
sb.add(")");
sb.add("$");
// sb.add("(");
// sb.add("(");
// sb.add("n");
// sb.add(")");
// sb.add("+");
// sb.add("i");
// sb.add(")");
// sb.add("$");
// sb.add("(");
// sb.add(")");
// sb.add("(");
// sb.add(")");
// sb.add("$");
RESULT:
Output 1:
Accepted:
Rejected String:
Output 2:
CONCLUSION: In this experiment, I developed an LL(1) parser using Java. To create the parsing table, I
used nested hashmaps. The LL(1) parsing algorithm was implemented using a stack and
the parsing table. The program defines a user-provided string as input and parses it using
the LL(1) parsing algorithm. If the parsing is successful and the stack is empty by the
end of the input string, the program accepts the string. Otherwise, if the stack is not
empty or the input string has not been fully processed, the program rejects the string.