/*
PseudoCode Interpreted Language (PCIL): Part of the algoviz@vt collection of algorithm visualizations.
Copyright (C) 2008 Brandon Malone, Frank Hadlock
This file is part of the PseudoCode Interpreted Language.
PseudoCode Interpreted Language is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the License,
or (at your option) any later version.
PseudoCode Interpreted Language is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.
You should have received a copy of the GNU General Public License along with
PseudoCode Interpreted Language. If not, see
.
*/
/*
* GrammarRule.java
*
* Created on March 2, 2008, 6:42 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package syntacticanalysis;
import java.util.ArrayList;
/**
*
* @author Brandon
*/
public class GrammarRule {
private Nonterminal lhs;
private ArrayList rhs;
public GrammarRule(Nonterminal lhs, ArrayList rhs) {
this.setLhs(lhs);
this.setRhs(rhs);
}
public GrammarRule(String line) {
// parse the grammar tokens of the rule
// assume of the form: ->
StringBuilder l = new StringBuilder();
l.append(line);
parseLhs(l);
// strip off everything before the rhs
stripBeforeRhs(l);
parseRhs(l);
}
private void parseLhs(StringBuilder line) {
// find the lhs
int index = line.indexOf(">");
String lhs = line.substring(1, index);
this.setLhs(new Nonterminal(lhs));
}
private void stripBeforeRhs(StringBuilder line) {
// find the beginning of the rhs
// it could be a '<' or '[' or '{'
int indexAngle = line.indexOf("<", 1);
int indexSquare = line.indexOf("[", 1);
int indexCurly = line.indexOf("{", 1);
int beginningOfRhs = -1;
if (indexAngle > -1) {
beginningOfRhs = indexAngle;
}
if ((indexSquare > -1) && ((indexSquare < beginningOfRhs) || beginningOfRhs == -1)) {
beginningOfRhs = indexSquare;
}
if ((indexCurly > -1) && ((indexCurly < beginningOfRhs) || beginningOfRhs == -1)) {
beginningOfRhs = indexCurly;
}
line.replace(0, beginningOfRhs, "");
}
private void parseRhs(StringBuilder rhs) {
this.rhs = new ArrayList();
// find the rhs
GrammarToken t = parseNextToken(rhs);
while (t != null) {
this.getRhs().add(t);
t = parseNextToken(rhs);
}
}
// find the first token and strip it off
private GrammarToken parseNextToken(StringBuilder line) {
if (line.length() == 0) {
return null;
}
// what is the first token?
String firstChar = String.valueOf(line.charAt(0));
if (firstChar.equals("[")) {
// terminal
return parseTerminal(line);
} else if (firstChar.equals("<")) {
// nonterminal
return parseNonterminal(line);
} else if (firstChar.equals("{")) {
// action symbol
return parseActionSymbol(line);
}
return null;
}
private Terminal parseTerminal(StringBuilder line) {
int index = line.indexOf("]");
String name = line.substring(1, index);
Terminal t = new Terminal(name);
// strip off the token
line.replace(0, index + 1, "");
return t;
}
private Nonterminal parseNonterminal(StringBuilder line) {
int index = line.indexOf(">");
String name = line.substring(1, index);
Nonterminal n = new Nonterminal(name);
// strip off the token
line.replace(0, index + 1, "");
return n;
}
private ActionSymbol parseActionSymbol(StringBuilder line) {
int index = line.indexOf("}");
String name = line.substring(1, index);
ActionSymbol a = new ActionSymbol(name);
// strip off the token
line.replace(0, index + 1, "");
return a;
}
public Nonterminal getLhs() {
return lhs;
}
public void setLhs(Nonterminal lhs) {
this.lhs = lhs;
}
public ArrayList getRhs() {
return rhs;
}
public void setRhs(ArrayList rhs) {
this.rhs = rhs;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(lhs.toString());
sb.append("->");
for(GrammarToken t : rhs) {
sb.append(t.toString());
}
return sb.toString();
}
}