Вы находитесь на странице: 1из 45

A Mini Project Report

on
CLR PARSER USING JAVA

By

DIVYA DASIKA

1602-16-733-009

EESHA CHAWHAN

1602-16-733-009

Department of Computer Science & Engineering


Vasavi College of Engineering (Autonomous)
(Affiliated to Osmania University)
Ibrahimbagh, Hyderabad-31

2018-19
SOURCE CODE

LR1item.java

package lr1;

import lr0.LR0Item;

import java.util.Arrays;

import java.util.HashSet;

import java.util.Objects;

public class LR1Item {

private HashSet<String> lookahead;

private String leftSide;

private String[] rightSide;

private int dotPointer;

public LR1Item(String leftSide, String[] rightSide, int dotPointer, HashSet<String>


lookahead){
this.leftSide = leftSide;

this.rightSide = rightSide;

this.dotPointer = dotPointer;

this.lookahead = lookahead;

public String getCurrent(){

if(dotPointer == rightSide.length){

return null;

return rightSide[dotPointer];

boolean goTo() {

if (dotPointer >= rightSide.length) {

return false;

dotPointer++;

return true;

public int getDotPointer() {


return dotPointer;

public String[] getRightSide() {

return rightSide;

public HashSet<String> getLookahead() {

return lookahead;

public String getLeftSide() {

return leftSide;

public void setLookahead(HashSet<String> lookahead) {

this.lookahead = lookahead;

public void setRightSide(String[] rightSide) {

this.rightSide = rightSide;

}
@Override

public boolean equals(Object o) {

if (this == o) return true;

if (o == null || getClass() != o.getClass()) return false;

LR1Item lr1Item = (LR1Item) o;

return dotPointer == lr1Item.dotPointer &&

Objects.equals(lookahead, lr1Item.lookahead) &&

Objects.equals(leftSide, lr1Item.leftSide) &&

Arrays.equals(rightSide, lr1Item.rightSide);

public boolean equalLR0(LR1Item item){

return leftSide.equals(item.getLeftSide()) &&


Arrays.equals(rightSide,item.getRightSide()) && dotPointer == item.getDotPointer();

@Override

public int hashCode() {

int hash = 7;

hash = 31 * hash + this.dotPointer;

hash = 31 * hash + Objects.hashCode(this.leftSide);

hash = 31 * hash + Arrays.deepHashCode(this.rightSide);


hash = 31 * hash + Objects.hashCode(this.lookahead);

return hash;

@Override

public String toString() {

String str = leftSide + " -> ";

for (int i = 0; i < rightSide.length; i++) {

if (i == dotPointer) {

str += ".";

str += rightSide[i];

if(i != rightSide.length - 1){

str+= " ";

if (rightSide.length == dotPointer) {

str += ".";

str += " , " + lookahead;

return str;

}
}

LR1parser.java

package lr1;

import lr0.LR0Item;

import util.*;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.HashSet;

public class LR1Parser extends LRParser {

private ArrayList<LR1State> canonicalCollection;

public LR1Parser(Grammar grammar){

super(grammar);

protected void createStatesForCLR1() {

canonicalCollection = new ArrayList<>();

HashSet<LR1Item> start = new HashSet<>();


Rule startRule = grammar.getRules().get(0);

HashSet<String> startLockahead = new HashSet<>();

startLockahead.add("$");

start.add(new
LR1Item(startRule.getLeftSide(),startRule.getRightSide(),0,startLockahead));

LR1State startState = new LR1State(grammar, start);

canonicalCollection.add(startState);

for (int i = 0; i < canonicalCollection.size(); i++) {

HashSet<String> stringWithDot = new HashSet<>();

for (LR1Item item : canonicalCollection.get(i).getItems()) {

if (item.getCurrent() != null) {

stringWithDot.add(item.getCurrent());

for (String str : stringWithDot) {

HashSet<LR1Item> nextStateItems = new HashSet<>();

for (LR1Item item : canonicalCollection.get(i).getItems()) {

if (item.getCurrent() != null && item.getCurrent().equals(str)) {

LR1Item temp = new


LR1Item(item.getLeftSide(),item.getRightSide(),item.getDotPointer()+1,item.getLoo
kahead());
nextStateItems.add(temp);

LR1State nextState = new LR1State(grammar, nextStateItems);

boolean isExist = false;

for (int j = 0; j < canonicalCollection.size(); j++) {

if (canonicalCollection.get(j).getItems().containsAll(nextState.getItems())

&&
nextState.getItems().containsAll(canonicalCollection.get(j).getItems())) {

isExist = true;

canonicalCollection.get(i).getTransition().put(str,
canonicalCollection.get(j));

if (!isExist) {

canonicalCollection.add(nextState);

canonicalCollection.get(i).getTransition().put(str, nextState);

}
public boolean parseCLR1(){

createStatesForCLR1();

createGoToTable();

return createActionTable();

public boolean parseLALR1(){

createStatesForLALR1();

createGoToTable();

return createActionTable();

public void createStatesForLALR1(){

createStatesForCLR1();

ArrayList<LR1State> temp = new ArrayList<>();

for (int i = 0; i < canonicalCollection.size(); i++) {

HashSet<String> lookahead = new HashSet<>();

HashSet<LR0Item> itemsi = new HashSet<>();

for(LR1Item item:canonicalCollection.get(i).getItems()){

itemsi.add(new
LR0Item(item.getLeftSide(),item.getRightSide(),item.getDotPointer()));

for (int j = i+1; j < canonicalCollection.size(); j++) {


HashSet<LR0Item> itemsj = new HashSet<>();

for(LR1Item item:canonicalCollection.get(j).getItems()){

itemsj.add(new
LR0Item(item.getLeftSide(),item.getRightSide(),item.getDotPointer()));

if(itemsi.containsAll(itemsj) && itemsj.containsAll(itemsi)){

for(LR1Item itemi : canonicalCollection.get(i).getItems()){

for(LR1Item itemj : canonicalCollection.get(j).getItems()){

if(itemi.equalLR0(itemj)){

itemi.getLookahead().addAll(itemj.getLookahead());

break;

for (int k = 0; k < canonicalCollection.size(); k++) {

for(String s : canonicalCollection.get(k).getTransition().keySet()){

if(canonicalCollection.get(k).getTransition().get(s).getItems().containsAll(canonicalC
ollection.get(j).getItems()) &&

canonicalCollection.get(j).getItems().containsAll(canonicalCollection.get(k).getTrans
ition().get(s).getItems())){

canonicalCollection.get(k).getTransition().put(s,canonicalCollection.get(i));

}
}

canonicalCollection.remove(j);

j--;

temp.add(canonicalCollection.get(i));

canonicalCollection = temp;

protected void createGoToTable() {

goToTable = new HashMap[canonicalCollection.size()];

for (int i = 0; i < goToTable.length; i++) {

goToTable[i] = new HashMap<>();

for (int i = 0; i < canonicalCollection.size(); i++) {

for (String s : canonicalCollection.get(i).getTransition().keySet()) {

if (grammar.isVariable(s)) {

goToTable[i].put(s,
findStateIndex(canonicalCollection.get(i).getTransition().get(s)));

}
}

private int findStateIndex(LR1State state) {

for (int i = 0; i < canonicalCollection.size(); i++) {

if (canonicalCollection.get(i).equals(state)) {

return i;

return -1;

private boolean createActionTable() {

actionTable = new HashMap[canonicalCollection.size()];

for (int i = 0; i < goToTable.length; i++) {

actionTable[i] = new HashMap<>();

for (int i = 0; i < canonicalCollection.size(); i++) {

for (String s : canonicalCollection.get(i).getTransition().keySet()) {

if (grammar.getTerminals().contains(s)) {

actionTable[i].put(s, new Action(ActionType.SHIFT,


findStateIndex(canonicalCollection.get(i).getTransition().get(s))));
}

for (int i = 0; i < canonicalCollection.size(); i++) {

for (LR1Item item : canonicalCollection.get(i).getItems()) {

if (item.getDotPointer() == item.getRightSide().length) {

if (item.getLeftSide().equals("S'")) {

actionTable[i].put("$", new Action(ActionType.ACCEPT, 0));

} else {

Rule rule = new Rule(item.getLeftSide(), item.getRightSide().clone());

int index = grammar.findRuleIndex(rule);

Action action = new Action(ActionType.REDUCE, index);

for (String str : item.getLookahead()) {

if (actionTable[i].get(str) != null) {

System.out.println("it has a REDUCE-" +


actionTable[i].get(str).getType() + " confilct in state " + i);

return false;

} else {

actionTable[i].put(str, action);

}
}

return true;

public String canonicalCollectionStr() {

String str = "Canonical Collection : \n";

for (int i = 0; i < canonicalCollection.size(); i++) {

str += "State " + i + " : \n";

str += canonicalCollection.get(i)+"\n";

return str;

}
LR1state.java

package lr1;

import util.Grammar;

import util.Rule;

import java.util.HashMap;

import java.util.HashSet;

import java.util.LinkedHashSet;

import java.util.Objects;

public class LR1State {

private LinkedHashSet<LR1Item> items;

private HashMap<String,LR1State> transition;

public LR1State(Grammar grammar,HashSet<LR1Item> coreItems){

items = new LinkedHashSet<>(coreItems);

transition = new HashMap<>();

closure(grammar);

}
private void closure(Grammar grammar) {

boolean changeFlag = false;

do {

changeFlag = false;

HashSet<LR1Item> temp = new HashSet<>();

for(LR1Item item : items){

if(item.getDotPointer() != item.getRightSide().length &&


grammar.isVariable(item.getCurrent())){

HashSet<String> lookahead = new HashSet<>();

if(item.getDotPointer() == item.getRightSide().length - 1){

lookahead.addAll(item.getLookahead());

}else{

HashSet<String> firstSet =
grammar.computeFirst(item.getRightSide(),item.getDotPointer()+1);

if(firstSet.contains("epsilon")){

firstSet.remove("epsilon");

firstSet.addAll(item.getLookahead());

lookahead.addAll(firstSet);

HashSet<Rule> rules =
grammar.getRuledByLeftVariable(item.getCurrent());

for(Rule rule : rules){


temp.add(new
LR1Item(rule.getLeftSide(),rule.getRightSide(),0,lookahead));

if(!items.containsAll(temp)){

items.addAll(temp);

changeFlag = true;

} while (changeFlag);

public HashMap<String, LR1State> getTransition() {

return transition;

public LinkedHashSet<LR1Item> getItems() {

return items;

@Override

public String toString() {


String s = "";

for(LR1Item item:items){

s += item + "\n";

return s;

}
Action.java

package util;

public class Action {

private ActionType type;

private int operand;

public Action(ActionType type, int operand) {

this.type = type;

this.operand = operand;

@Override

public String toString() {

return type + " " + (type == ActionType.ACCEPT ? "":operand);

public ActionType getType() {

return type;

public int getOperand() {

return operand;

}
Actiontype.java

package util;

public enum ActionType {

ACCEPT,SHIFT,REDUCE

grammar.java

package util;

import java.io.BufferedReader;

import java.io.File;

import java.io.FileReader;

import java.io.IOException;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Objects;

public class Grammar {

private ArrayList<Rule> rules;


private HashSet<String> terminals;

private HashSet<String> variables;

private String startVariable;

private HashMap<String, HashSet<String>> firstSets;

private HashMap<String, HashSet<String>> fallowSets;

public Grammar(String s) {

rules = new ArrayList<>();

terminals = new HashSet<>();

variables = new HashSet<>();

int line = 0;

for(String st : s.split("\n")){

String[] sides = st.split("->");

String leftSide = sides[0].trim();

variables.add(leftSide);

String[] rulesRightSide = sides[1].trim().split("\\|");

for (String rule : rulesRightSide) {

String[] rightSide = rule.trim().split("\\s+");

for (String terminal : rightSide) {

terminals.add(terminal);

}
if (line == 0) {

startVariable = leftSide;

rules.add(new Rule("S'", new String[]{startVariable}));

rules.add(new Rule(leftSide, rightSide));

line++;

for (String variable : variables) {

terminals.remove(variable);

System.out.println("Rules: ");

for (int i=0 ; i<rules.size() ; i++) {

System.out.println(i+" : " +rules.get(i));

computeFirstSets();

computeFollowSet();

public ArrayList<Rule> getRules() {


return rules;

public int findRuleIndex(Rule rule){

for(int i=0 ; i<rules.size();i++){

if(rules.get(i).equals(rule)){

return i;

return -1;

public HashSet<String> getVariables() {

return variables;

public String getStartVariable() {

return startVariable;

private void computeFirstSets() {

firstSets = new HashMap<>();


for (String s : variables) {

HashSet<String> temp = new HashSet<>();

firstSets.put(s, temp);

while (true) {

boolean isChanged = false;

for (String variable : variables) {

HashSet<String> firstSet = new HashSet<>();

for (Rule rule : rules) {

if (rule.getLeftSide().equals(variable)) {

HashSet<String> addAll = computeFirst(rule.getRightSide(), 0);

firstSet.addAll(addAll);

if (!firstSets.get(variable).containsAll(firstSet)) {

isChanged = true;

firstSets.get(variable).addAll(firstSet);

if (!isChanged) {
break;

firstSets.put("S'", firstSets.get(startVariable));

private void computeFollowSet() {

fallowSets = new HashMap<>();

for (String s : variables) {

HashSet<String> temp = new HashSet<>();

fallowSets.put(s, temp);

HashSet<String> start = new HashSet<>();

start.add("$");

fallowSets.put("S'", start);

while (true) {

boolean isChange = false;

for (String variable : variables) {

for (Rule rule : rules) {

for (int i = 0; i < rule.getRightSide().length; i++) {


if (rule.getRightSide()[i].equals(variable)) {

if (i == rule.getRightSide().length - 1) {

fallowSets.get(variable).addAll(fallowSets.get(rule.leftSide));

} else {

HashSet<String> first = computeFirst(rule.getRightSide(), i + 1);

if (first.contains("epsilon")) {

first.remove("epsilon");

first.addAll(fallowSets.get(rule.leftSide));

if (!fallowSets.get(variable).containsAll(first)) {

isChange = true;

fallowSets.get(variable).addAll(first);

if (!isChange) {

break;

}
}

public HashSet<String> computeFirst(String[] string, int index) {

HashSet<String> first = new HashSet<>();

if (index == string.length) {

return first;

if (terminals.contains(string[index])) {

first.add(string[index]);

return first;

if (variables.contains(string[index])) {

for (String str : firstSets.get(string[index])) {

first.add(str);

if (first.contains("epsilon")) {

if (index != string.length - 1) {

first.addAll(computeFirst(string, index + 1));

first.remove("epsilon");
}

return first;

public HashSet<Rule> getRuledByLeftVariable(String variable) {

HashSet<Rule> variableRules = new HashSet<>();

for (Rule rule : rules) {

if (rule.getLeftSide().equals(variable)) {

variableRules.add(rule);

return variableRules;

public boolean isVariable(String s) {

return variables.contains(s);

public HashMap<String, HashSet<String>> getFirstSets() {

return firstSets;

}
public HashMap<String, HashSet<String>> getFallowSets() {

return fallowSets;

public HashSet<String> getTerminals() {

return terminals;

@Override

public int hashCode() {

int hash = 3;

hash = 37 * hash + Objects.hashCode(this.rules);

hash = 37 * hash + Objects.hashCode(this.terminals);

hash = 37 * hash + Objects.hashCode(this.variables);

return hash;

@Override

public boolean equals(Object obj) {

if (this == obj) {

return true;
}

if (obj == null) {

return false;

if (getClass() != obj.getClass()) {

return false;

final Grammar other = (Grammar) obj;

if (!Objects.equals(this.rules, other.rules)) {

return false;

if (!Objects.equals(this.terminals, other.terminals)) {

return false;

if (!Objects.equals(this.variables, other.variables)) {

return false;

return true;

@Override

public String toString() {


String str = "";

for(Rule rule: rules){

str += rule + "\n";

return str;

}
Actiontype.java

package util;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Stack;

public abstract class LRParser {

protected HashMap<String, Integer>[] goToTable;

protected HashMap<String, Action>[] actionTable;

protected Grammar grammar;

public LRParser(Grammar grammar) {

this.grammar = grammar;

protected abstract void createGoToTable();

public boolean accept(ArrayList<String> inputs) {


inputs.add("$");

int index = 0;

Stack<String> stack = new Stack<>();

stack.add("0");

while(index < inputs.size()){

int state = Integer.valueOf(stack.peek());

String nextInput = inputs.get(index);

Action action = actionTable[state].get(nextInput);

if(action == null){

return false;

}else if(action.getType() == ActionType.SHIFT){

stack.push(nextInput);

stack.push(action.getOperand()+"");

index++;

}else if(action.getType() == ActionType.REDUCE){

int ruleIndex = action.getOperand();

Rule rule = grammar.getRules().get(ruleIndex);

String leftSide = rule.getLeftSide();

int rightSideLength = rule.getRightSide().length;

for(int i=0; i <2*rightSideLength ; i++){

stack.pop();

}
int nextState = Integer.valueOf(stack.peek());

stack.push(leftSide);

int variableState = goToTable[nextState].get(leftSide);

stack.push(variableState+"");

}else if(action.getType() == ActionType.ACCEPT){

return true;

return false;

public String goToTableStr() {

String str = "Go TO Table : \n";

str += " ";

for (String variable : grammar.getVariables()) {

str += String.format("%-6s",variable);

str += "\n";

for (int i = 0; i < goToTable.length; i++) {

for (int j = 0; j < (grammar.getVariables().size()+1)*6+2; j++) {

str += "-";
}

str += "\n";

str += String.format("|%-6s|",i);

for (String variable : grammar.getVariables()) {

str += String.format("%6s",(goToTable[i].get(variable) == null ? "|" :


goToTable[i].get(variable)+"|"));

str += "\n";

for (int j = 0; j < (grammar.getVariables().size()+1)*6+2; j++) {

str += "-";

return str;

public String actionTableStr() {

String str = "Action Table : \n";

HashSet<String> terminals = new HashSet<>(grammar.getTerminals());

terminals.add("$");

str += " ";

for (String terminal : terminals) {

str += String.format("%-10s" , terminal);

}
str += "\n";

for (int i = 0; i < actionTable.length; i++) {

for (int j = 0; j < (terminals.size()+1)*10+2; j++) {

str += "-";

str += "\n";

str += String.format("|%-10s|",i);

for (String terminal : terminals) {

str += String.format("%10s",(actionTable[i].get(terminal) == null ? "|" :


actionTable[i].get(terminal) + "|"));

str += "\n";

for (int j = 0; j < (terminals.size()+1)*10+2; j++) {

str += "-";

return str;

public Grammar getGrammar() {

return grammar;

}}
Rule.java

package util;

import java.util.Arrays;

import java.util.Objects;

public class Rule {

protected String leftSide;

protected String[] rightSide;

public Rule(String leftSide, String[] rightSide) {

this.rightSide = rightSide;

this.leftSide = leftSide;

public Rule(Rule rule) {

this.leftSide = rule.getLeftSide();

this.rightSide = rule.rightSide.clone();

public String getLeftSide() {


return leftSide;

public String[] getRightSide() {

return rightSide;

@Override

public int hashCode() {

int hash = 3;

hash = 29 * hash + Objects.hashCode(this.leftSide);

hash = 29 * hash + Arrays.deepHashCode(this.rightSide);

return hash;

@Override

public boolean equals(Object obj) {

if (this == obj) {

return true;

if (obj == null) {

return false;
}

if (getClass() != obj.getClass()) {

return false;

final Rule other = (Rule) obj;

if (!Objects.equals(this.leftSide, other.leftSide)) {

return false;

if (!Arrays.deepEquals(this.rightSide, other.rightSide)) {

return false;

return true;

@Override

public String toString() {

String str = leftSide + " -> ";

for (int i = 0; i < rightSide.length; i++) {

str += rightSide[i] + " ";

return str;

}}
Main.java

package gui;

import javafx.application.Application;

import javafx.fxml.FXMLLoader;

import javafx.scene.Parent;

import javafx.scene.Scene;

import javafx.stage.Stage;

public class Main extends Application {

@Override

public void start(Stage primaryStage) throws Exception{

Parent root =
FXMLLoader.load(getClass().getResource("GrammarInput.fxml"));

primaryStage.setTitle("LR Parser");

primaryStage.setScene(new Scene(root));

primaryStage.show();

public static void main(String[] args) {

launch(args);
}

OUTPUT SCREENSHOTS

Вам также может понравиться