Find the first and follow set of a given grammar in java - java

I have been given the problem to complete, and the algorithms to find the first and follow, but my problem is I cant quite find a data structure to implement to find these sets.
import java.util.Stack;
public class FirstFollowSet {
private final String[] term_tokens = { "begin", "end", ";", "if", "then", "else", "fi", "i", "=", "+", "-", "*",
"/", "(", ")", "const" };
private final static String[] non_term_tokens = { "Start", "Prog", "Block", "Body", "S", "E", "T", "F" };
private static RuleStack rules;
private Stack<String> firstSet;
private Stack<String> followSet;
private boolean is_terminal(String str) {
boolean test = false;
for (int i = 0; i < term_tokens.length; i++) {
if (str.equals(term_tokens[i]))
test = true;
}
return test;
}
private boolean is_non_term(String str){
for(int i = 0; i < non_term_tokens.length; i++)
{
if(str.equals(non_term_tokens[i]))
{
return true;
}
}
return false;
}
private class Rule{
String def, token;
public Rule()
{
def = "";
token = "";
}
public Rule(String d, String t)
{
def = d;
token = t;
}
public String getDef() {
return def;
}
public String getToken() {
return token;
}
public String toString()
{
String str = "";
str+= token + " " + def + '\n';
return str;
}
}
public class RuleStack{
Stack<Rule> rules;
public RuleStack(String grammar)
{
if(grammar.equals("G1"));
{
rules = new Stack();
Rule rule = new Rule("Prog", "Start");
rules.push(rule);
rule = new Rule("Block #", "Prog");
rules.push(rule);
rule = new Rule("begin Body end", "Block");
rules.push(rule);
rule = new Rule("begin S end", "Body");
rules.push(rule);
rule = new Rule("Body ; S", "Body");
rules.push(rule);
rule = new Rule("S", "Body");
rules.push(rule);
rule = new Rule("if E then S else S fi", "S");
rules.push(rule);
rule = new Rule("if E else S fi", "S");
rules.push(rule);
rule = new Rule("i = E", "S");
rules.push(rule);
rule = new Rule("Block", "S");
rules.push(rule);
rule = new Rule("E + T", "E");
rules.push(rule);
rule = new Rule("E * T", "E");
rules.push(rule);
rule = new Rule("T", "E");
rules.push(rule);
rule = new Rule("T * F", "T");
rules.push(rule);
rule = new Rule("T / F", "T");
rules.push(rule);
rule = new Rule("F", "T");
rules.push(rule);
rule = new Rule("const", "F");
rules.push(rule);
rule = new Rule("( E )", "F");
rules.push(rule);
}
}
}
public FirstFollowSet()
{
rules = new RuleStack("G1");
firstSet = new Stack();
followSet = new Stack();
}
public String FindFirstSet(String str, Stack<String> used)
{
if(used.contains(str))
{
return null;
}
String firstToken = "";
String win = "";
if(str.indexOf(" ") != -1)
firstToken = str.substring(0, str.indexOf(" "));
else
firstToken = str;
if(is_terminal(firstToken))
{
if(!(firstSet.contains(firstToken)))
win = firstToken;
if(win.equals("") != true)
firstSet.push(win);
}
else if(is_non_term(firstToken) && !(used.contains(firstToken)))
{
used.push(firstToken);
if(firstToken.equals("lambda"))
{
if(!(firstSet.contains(firstToken)))
win = firstToken;
}
else
{
RuleStack rules = new RuleStack("G1");
while(rules.rules.isEmpty() != true)
{
Rule winner = rules.rules.pop();
if(winner.token.equals(firstToken))
{
String test = FindFirstSet(winner.def, used);
if(!(test.equals("lambda")))
{
if(!(firstSet.contains(test)))
win = test;
}
}
}
}
}
return win;
}
public String findFollowSet(String str)
{
if(str.equals("S"))
{
followSet.push("$");
}
for(int i = 0; i < non_term_tokens.length; i++)
{
if(str.contains(non_term_tokens[i]))
{
int index = str.indexOf(non_term_tokens[i]);
Stack<String> used = new Stack();
FirstFollowSet test = new FirstFollowSet();
if(index > 0 && index < str.length()-1)
{
test.FindFirstSet(str, used);
while(test.firstSet.isEmpty() != true)
{
String token = firstSet.pop();
if(!(token.equals("lambda")))
test.followSet.push(token);
}
}
else if(index > 0 && index == str.length()-1)
{
}
}
}
}
public static void main(String[] args) {
FirstFollowSet test = new FirstFollowSet();
Stack<String> used = new Stack();
test.FindFirstSet("S", used);
while(test.firstSet.isEmpty() != true)
{
String str = test.firstSet.pop();
System.out.println(str);
}
}
}
This is the code I have so far, and the find first set works just fine, but the findfollowset method I'm not quite sure how to implement. The only idea I can seem to come up with is making a stack for each non-terminal symbol, apply the algorithm, and add each terminal symbol returned to the set it belongs to. This method just feel like its more work then necessary.
If anyone has ever solved this problem, or has seen a way to solve this problem I would just like to know what sort of data structure was used and how it the algorithm was implemented for said structure.
Thank you for taking the time to read this, and i appreciate any feedback given.

package modelo;
import java.util.ArrayList;
/**
*
* #author celeste
*/
public class Axioma {
public char getSimbolo() {
return simbolo;
}
public void setSimbolo(char simbolo) {
this.simbolo = simbolo;
}
public ArrayList<Character> getPrimeros() {
return primeros;
}
public void setPrimeros(ArrayList<Character> primeros) {
this.primeros = primeros;
}
public ArrayList<Character> getSiguientes() {
return siguientes;
}
public void setSiguientes(ArrayList<Character> siguientes) {
this.siguientes = siguientes;
}
public ArrayList<Character> getPredictivos() {
return predictivos;
}
public void setPredictivos(ArrayList<Character> predictivos) {
this.predictivos = predictivos;
}
public ArrayList<Character> getRegla() {
return regla;
}
public void setRegla(ArrayList<Character> regla) {
this.regla = regla;
}
private ArrayList<Character> primeros = new ArrayList<>();
private ArrayList<Character> siguientes = new ArrayList<>();
private ArrayList<Character> predictivos = new ArrayList<>();
private ArrayList<Character> regla = new ArrayList<>();
private char simbolo;
}

Related

Java - printing all ArrayList elements as a single String

My program prints out a library. Each library is composed of books. Each book is composed of a title and the authors of that book. I have a driver program, a Library class, and a Book class. My issue is that when I use my driver program that uses my toString() methods in the library and book classes to print the library, the authors of each book are appearing as [author, ;, author, ;, author] and I want them to print as author; author; author.
Expected output: http://prntscr.com/810ik2
My output: http://prntscr.com/810ipp
My input: http://prntscr.com/810j6f
getAuthors is the method in my driver program that separates the authors (In the input file that the authors are taken from authors are separated by '*' instead of separated by ';' which is what i need in my output)
Please let me know in the comments if there is too little info, too much info, if what I've given is too confusing, or if I didn't explain anything properly. I'm new to Java and fairly new at posting questions here so please go easy on me. Thank you!
Edit: Just in case here are my three classes (only the important stuff):
Book.java:
import java.util.*;
public class Book implements Comparable<Book>
{
private final String myTitle;
private final ArrayList<String> myAuthors;
public Book(final String theTitle, final ArrayList<String> theAuthors)
{
if (theTitle == "" || theAuthors.isEmpty() ||
theTitle == null || theAuthors.get(0) == null)
{
throw new IllegalArgumentException(
"The book must have a valid title AND author.");
}
else
{
myTitle = theTitle;
myAuthors = new ArrayList<String>();
for (int i = 0; i < theAuthors.size(); i++)
{
myAuthors.add(theAuthors.get(i));
}
}
}
public String toString()
{
String result = "\"" + myTitle + "\" by ";
for (int i = 0; i < myAuthors.size(); i++)
{
result += (String)myAuthors.get(i);
}
return result;
}
}
Library.java:
import java.util.*;
public class Library
{
public Library(final ArrayList<Book> theOther)
{
if (theOther == null)
{
throw new NullPointerException();
}
else
{
myBooks = new ArrayList<Book>();
for (int i = 0; i < theOther.size(); i++)
{
myBooks.add(theOther.get(i));
}
}
}
public ArrayList<Book> findTitles(final String theTitle)
{
ArrayList<Book> titleList = new ArrayList<Book>();
for (int i = 0; i < myBooks.size(); i++)
{
if (myBooks.get(i).getTitle().equals(theTitle))
{
titleList.add(myBooks.get(i));
}
}
return titleList;
}
public String toString()
{
String result = "";
for (int i = 0; i < myBooks.size(); i++)
{
String tempTitle = myBooks.get(i).getTitle();
ArrayList<String> tempAuthors = myBooks.get(i).getAuthors();
Book tempBook = new Book(tempTitle, tempAuthors);
result += (tempBook + "\n");
}
return result;
}
}
LibraryDriver.java:
import java.util.*;
import java.io.*;
public class LibraryDriver
{
public static void main(String[] theArgs)
{
Scanner inputFile = null;
PrintStream outputFile = null;
ArrayList<String> authors = new ArrayList<String>();
ArrayList<Book> books = new ArrayList<Book>();
ArrayList<Book> books2 = new ArrayList<Book>();
String[] filesInputs = new String[]{"LibraryIn1.txt", "LibraryIn2.txt"};
try
{
outputFile = new PrintStream(new File("LibraryOut.txt"));
for (String fileInput : filesInputs)
{
inputFile = new Scanner(new File(fileInput));
while (inputFile.hasNext())
{
String title = "";
String input = inputFile.nextLine();
//Read title
title = input;
input = inputFile.nextLine();
authors = getAuthors(input);
//Insert title & authors into a book
Book tempBook = new Book(title, authors);
//Add this book to the ArrayList<Book> of books
books.add(tempBook);
}
Library myLib = new Library(books);
outputFile.println(myLib);
inputFile.close();
myLib.sort();
outputFile.println(myLib);
}
}
catch (Exception e)
{
System.out.println("Difficulties opening the file! " + e);
System.exit(1);
}
inputFile.close();
outputFile.close();
}
public static ArrayList<String> getAuthors(String theAuthors)
{
int lastAsteriskIndex = 0;
ArrayList<String> authorList = new ArrayList<String>();
for (int i = 0; i < theAuthors.length(); i++)
{
if (theAuthors.charAt(i) == '*')
{
if (lastAsteriskIndex > 0)
{
authorList.add(";");
authorList.add(theAuthors.substring(lastAsteriskIndex + 1, i));
}
else
{
authorList.add(theAuthors.substring(0, i));
}
lastAsteriskIndex = i;
}
}
if (lastAsteriskIndex == 0)
{
authorList.add(theAuthors);
}
return authorList;
}
}
So, I hobbled together a runnable example of your code as best as I could and using
The Hobbit
Tolkien, J.R.R
Acer Dumpling
Doofus, Robert
As input, I get
"The Hobbit" by Tolkien, J.R.R
"Acer Dumpling" by Doofus, Robert
The code:
import java.io.File;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Scanner;
public class LibraryDriver {
public static void main(String[] theArgs) {
// ArrayList<Book> books = new ArrayList<>(25);
// books.add(
// new Book("Bananas in pajamas",
// new ArrayList<>(Arrays.asList(new String[]{"B1", "B2"}))));
//
// Library lib = new Library(books);
// System.out.println(lib.toString());
Scanner inputFile = null;
PrintStream outputFile = null;
ArrayList<String> authors = new ArrayList<String>();
ArrayList<Book> books = new ArrayList<Book>();
ArrayList<Book> books2 = new ArrayList<Book>();
String[] filesInputs = new String[]{"LibraryIn1.txt"}; //, "LibraryIn2.txt"};
try {
outputFile = new PrintStream(new File("LibraryOut.txt"));
for (String fileInput : filesInputs) {
inputFile = new Scanner(new File(fileInput));
while (inputFile.hasNext()) {
String title = "";
String input = inputFile.nextLine();
//Read title
title = input;
input = inputFile.nextLine();
authors = getAuthors(input);
//Insert title & authors into a book
Book tempBook = new Book(title, authors);
//Add this book to the ArrayList<Book> of books
books.add(tempBook);
}
Library myLib = new Library(books);
outputFile.println(myLib);
inputFile.close();
// myLib.sort();
// outputFile.println(myLib);
}
} catch (Exception e) {
System.out.println("Difficulties opening the file! " + e);
System.exit(1);
}
inputFile.close();
outputFile.close();
}
public static ArrayList<String> getAuthors(String theAuthors) {
int lastAsteriskIndex = 0;
ArrayList<String> authorList = new ArrayList<String>();
for (int i = 0; i < theAuthors.length(); i++) {
if (theAuthors.charAt(i) == '*') {
if (lastAsteriskIndex > 0) {
authorList.add(";");
authorList.add(theAuthors.substring(lastAsteriskIndex + 1, i));
} else {
authorList.add(theAuthors.substring(0, i));
}
lastAsteriskIndex = i;
}
}
if (lastAsteriskIndex == 0) {
authorList.add(theAuthors);
}
return authorList;
}
public static class Library {
private ArrayList<Book> myBooks;
public Library(final ArrayList<Book> theOther) {
if (theOther == null) {
throw new NullPointerException();
} else {
myBooks = new ArrayList<Book>();
for (int i = 0; i < theOther.size(); i++) {
myBooks.add(theOther.get(i));
}
}
}
public ArrayList<Book> findTitles(final String theTitle) {
ArrayList<Book> titleList = new ArrayList<Book>();
for (int i = 0; i < myBooks.size(); i++) {
if (myBooks.get(i).getTitle().equals(theTitle)) {
titleList.add(myBooks.get(i));
}
}
return titleList;
}
public String toString() {
String result = "";
for (int i = 0; i < myBooks.size(); i++) {
String tempTitle = myBooks.get(i).getTitle();
Book b = myBooks.get(i);
ArrayList<String> tempAuthors = b.getAuthors();
Book tempBook = new Book(tempTitle, tempAuthors);
result += (tempBook + "\n");
}
return result;
}
}
public static class Book implements Comparable<Book> {
private final String myTitle;
private final ArrayList<String> myAuthors;
public Book(final String theTitle, final ArrayList<String> theAuthors) {
if (theTitle == "" || theAuthors.isEmpty()
|| theTitle == null || theAuthors.get(0) == null) {
throw new IllegalArgumentException(
"The book must have a valid title AND author.");
} else {
myTitle = theTitle;
myAuthors = new ArrayList<String>();
for (int i = 0; i < theAuthors.size(); i++) {
myAuthors.add(theAuthors.get(i));
}
}
}
public String toString() {
String result = "\"" + myTitle + "\" by ";
for (int i = 0; i < myAuthors.size(); i++) {
result += (String) myAuthors.get(i);
}
return result;
}
#Override
public int compareTo(Book o) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public String getTitle() {
return myTitle;
}
public ArrayList<String> getAuthors(String theAuthors) {
int lastAsteriskIndex = 0;
ArrayList<String> authorList = new ArrayList<String>();
for (int i = 0; i < theAuthors.length(); i++) {
if (theAuthors.charAt(i) == '*') {
if (lastAsteriskIndex > 0) {
authorList.add(";");
authorList.add(theAuthors.substring(lastAsteriskIndex + 1, i));
} else {
authorList.add(theAuthors.substring(0, i));
}
lastAsteriskIndex = i;
}
}
if (lastAsteriskIndex == 0) {
authorList.add(theAuthors);
}
return authorList;
}
public ArrayList<String> getAuthors() {
return myAuthors;
}
}
}
Consider providing a runnable example which demonstrates your problem. This is not a code dump, but an example of what you are doing which highlights the problem you are having. This will result in less confusion and better responses

Found some code for serialization of an ItemStack in Bukkit, how to deserialize it?

I've dug up the following code for serializing an ItemStack in bukkit (Minecraft). I've been able to serialize an item in hand with the following:
itemString = ItemStackUtils.deserialize(player.getInventory().getItemInHand());
I can't figure out how to utilize the deserial call however. What I am trying to do is to pull an item from the players hand, serialize it, stick it into a config file, then when the player runs another command... deserialize it and slap it into their inventory. I am fairly certain this class will meet my needs if I just can get the last part working.
public final class ItemStackUtils {
public static String getEnchants(ItemStack i){
List<String> e = new ArrayList<String>();
Map<Enchantment, Integer> en = i.getEnchantments();
for(Enchantment t : en.keySet()) {
e.add(t.getName() + ":" + en.get(t));
}
return StringUtils.join(e, ",");
}
public static String deserialize(ItemStack i){
String[] parts = new String[6];
parts[0] = i.getType().name();
parts[1] = Integer.toString(i.getAmount());
parts[2] = String.valueOf(i.getDurability());
parts[3] = i.getItemMeta().getDisplayName();
parts[4] = String.valueOf(i.getData().getData());
parts[5] = getEnchants(i);
return StringUtils.join(parts, ";");
}
public ItemStack deserial(String p){
String[] a = p.split(";");
ItemStack i = new ItemStack(Material.getMaterial(a[0]), Integer.parseInt(a[1]));
i.setDurability((short) Integer.parseInt(a[2]));
ItemMeta meta = i.getItemMeta();
meta.setDisplayName(a[3]);
i.setItemMeta(meta);
MaterialData data = i.getData();
data.setData((byte) Integer.parseInt(a[4]));
i.setData(data);
if (a.length > 5) {
String[] parts = a[5].split(",");
for (String s : parts) {
String label = s.split(":")[0];
String amplifier = s.split(":")[1];
Enchantment type = Enchantment.getByName(label);
if (type == null)
continue;
int f;
try {
f = Integer.parseInt(amplifier);
} catch(Exception ex) {
continue;
}
i.addEnchantment(type, f);
}
}
return i;
}
}
here it saves & loads the whole NBT
package XXXXXXXXX
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.material.MaterialData;
import net.minecraft.server.v1_8_R3.MojangsonParseException;
import net.minecraft.server.v1_8_R3.MojangsonParser;
import net.minecraft.server.v1_8_R3.NBTTagCompound;
public class ItemSerialize {
public ItemSerialize() {
}
public static String serialize(ItemStack i) {
String[] parts = new String[7];
parts[0] = i.getType().name();
parts[1] = Integer.toString(i.getAmount());
parts[2] = String.valueOf(i.getDurability());
parts[3] = i.getItemMeta().getDisplayName();
parts[4] = String.valueOf(i.getData().getData());
parts[5] = getEnchants(i);
parts[6] = getNBT(i);
return StringUtils.join(parts, ";");
}
public static String getEnchants(ItemStack i) {
List<String> e = new ArrayList<String>();
Map<Enchantment, Integer> en = i.getEnchantments();
for (Enchantment t : en.keySet()) {
e.add(t.getName() + ":" + en.get(t));
}
return StringUtils.join(e, ",");
}
public static String getLore(ItemStack i) {
List<String> e = i.getItemMeta().getLore();
return StringUtils.join(e, ",");
}
public static String getNBT(ItemStack i) {
net.minecraft.server.v1_8_R3.ItemStack nmsStack = CraftItemStack.asNMSCopy(i);
NBTTagCompound compound = nmsStack.hasTag() ? nmsStack.getTag() : new NBTTagCompound();
return compound.toString();
}
public static ItemStack setNBT(ItemStack i, String NBT) {
net.minecraft.server.v1_8_R3.ItemStack nmsStack = CraftItemStack.asNMSCopy(i);
try {
NBTTagCompound compound = MojangsonParser.parse(NBT);
nmsStack.setTag(compound);
} catch (MojangsonParseException e1) {
e1.printStackTrace();
}
return CraftItemStack.asBukkitCopy(nmsStack);
}
#SuppressWarnings("deprecation")
public static ItemStack deserial(String p) {
String[] a = p.split(";");
ItemStack i = new ItemStack(Material.getMaterial(a[0]), Integer.parseInt(a[1]));
i.setDurability((short) Integer.parseInt(a[2]));
ItemMeta meta = i.getItemMeta();
meta.setDisplayName(a[3]);
i.setItemMeta(meta);
MaterialData data = i.getData();
data.setData((byte) Integer.parseInt(a[4]));
i.setData(data);
if (!a[6].isEmpty()) {
i = setNBT(i, a[6]);
}
if (!a[5].isEmpty()) {
String[] parts = a[5].split(",");
for (String s : parts) {
String label = s.split(":")[0];
String amplifier = s.split(":")[1];
Enchantment type = Enchantment.getByName(label);
if (type == null)
continue;
int f;
try {
f = Integer.parseInt(amplifier);
} catch (Exception ex) {
continue;
}
i.addUnsafeEnchantment(type, f);
}
}
return i;
}
}
ItemStack rItem = ItemStackUtils.deserial(itemString);

error cannot find symbol and class discrete Attribute

import java.io.*;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class FileReader
{
public static final String PATH_TO_DATA_FILE = "playtennis.data";
public static ArrayList<Record> buildRecords() {
BufferedReader reader = null;
DataInputStream dis = null;
ArrayList<Record> records = new ArrayList<Record>();
try {
File f = new File(PATH_TO_DATA_FILE);
FileInputStream fis = new FileInputStream(f);
reader = new BufferedReader(new InputStreamReader(fis));;
// read the first record of the file
String line;
Record r = null;
ArrayLAist<DiscreteAttribute> attributes;
while ((line = reader.readLine()) != null) {
StringTokenizer st = new StringTokenizer(line, ",");
attributes = new ArrayList<DiscreteAttribute>();
r = new Record();
if(Hw1.NUM_ATTRS != st.countTokens()) {
throw new Exception("Unknown number of attributes!");
}
#SuppressWarnings("unused")
String day = st.nextToken();
String outlook = st.nextToken();
String temperature = st.nextToken();
String humidity = st.nextToken();
String wind = st.nextToken();
String playTennis = st.nextToken();
if(outlook.equalsIgnoreCase("overcast")) {
attributes.add(new DiscreteAttribute("Outlook", DiscreteAttribute.Overcast));
}
else if(outlook.equalsIgnoreCase("sunny")) {
attributes.add(new DiscreteAttribute("Outlook", DiscreteAttribute.Sunny));
}
else if(outlook.equalsIgnoreCase("rain")) {
attributes.add(new DiscreteAttribute("Outlook", DiscreteAttribute.Rain));
}
if(temperature.equalsIgnoreCase("hot")) {
attributes.add(new DiscreteAttribute("Temperature", DiscreteAttribute.Hot));
}
else if(temperature.equalsIgnoreCase("mild")) {
attributes.add(new DiscreteAttribute("Temperature", DiscreteAttribute.Mild));
}
else if(temperature.equalsIgnoreCase("cool")) {
attributes.add(new DiscreteAttribute("Temperature", DiscreteAttribute.Cool));
}
if(humidity.equalsIgnoreCase("high")) {
attributes.add(new DiscreteAttribute("Humidity", DiscreteAttribute.High));
}
else if(humidity.equalsIgnoreCase("normal")) {
attributes.add(new DiscreteAttribute("Humidity", DiscreteAttribute.Normal));
}
if(wind.equalsIgnoreCase("weak")) {
attributes.add(new DiscreteAttribute("Wind", DiscreteAttribute.Weak));
}
else if(wind.equalsIgnoreCase("strong")) {
attributes.add(new DiscreteAttribute("Wind", DiscreteAttribute.Strong));
}
if(playTennis.equalsIgnoreCase("no")) {
attributes.add(new DiscreteAttribute("PlayTennis", DiscreteAttribute.PlayNo));
}
else if(playTennis.equalsIgnoreCase("yes")) {
attributes.add(new DiscreteAttribute("PlayTennis", DiscreteAttribute.PlayYes));
}
r.setAttributes(attributes);
records.add(r);
}
}
}
I haven given file name as FileReader
I'm getting errors on cannot file symbol
Cannot find symbol symbol:class discrete Attribute, location:class classifier.FileReader
Cannot find the symbol symbol:variable discrete Attribute location:class classifier.FileReader
Here DiscreteAttribute class. You need add that class your project.
public class DiscreteAttribute extends Attribute { public static final int Sunny = 0; public static final int Overcast = 1; public static final int Rain = 2; public static final int Hot = 0; public static final int Mild = 1; public static final int Cool = 2; public static final int High = 0; public static final int Normal = 1; public static final int Weak = 0; public static final int Strong = 1; public static final int PlayNo = 0; public static final int PlayYes = 1; enum PlayTennis { No, Yes } enum Wind { Weak, Strong } enum Humidity { High, Normal } enum Temp { Hot, Mild, Cool } enum Outlook { Sunny, Overcast, Rain } public DiscreteAttribute(String name, double value) { super(name, value); } public DiscreteAttribute(String name, String value) { super(name, value); } }

Parsing a String into a Map in Java

have a string like;
{uniqueKey=test20745,content={acostumbrado={tf=1,df=1},al={tf=1,df=6945},ante={tf=1,df=42},co={tf=1,df=9187},ello={tf=1,df=2},está={tf=2,df=21},falcao={tf=1,df=105},guardia={tf=1,df=2},http={tf=1,df=9893},nada={tf=1,df=24},no={tf=1,df=2493},osa={tf=1,df=429},para={tf=1,df=6382},partido={tf=1,df=50},pretorian={tf=1,df=1},que={tf=1,df=358},sebcfkeı={tf=1,df=1},su={tf=1,df=7368},t={tf=1,df=14423},tuvo={tf=1,df=3},un={tf=1,df=8511}}}
how to parse this string to a map(key, list) like below;
acostumbrado->tf=1,df=1
al ->tf=1,df=6945
ante ->tf=1,df=42
...
edit:
so what I have done up to now;
String delims = "[{},]";
HashMap<String, List<String>> valueMap = new HashMap<String, List<String>>();
for (int i = 0; i < text.size(); i++) {
String[] tokens = val.toString().split(delims);
ArrayList<String> tfAndDfValues = new ArrayList<String>();
tfAndDfValues.add(tokens[4].substring(3));
tfAndDfValues.add(tokens[5].substring(3));
if (valueMap.containsKey(removeLastChar(tokens[3]))) {
valueMap.get(removeLastChar(tokens[3])).addAll(tfAndDfValues);
} else {
valueMap.put(removeLastChar(tokens[3]), tfAndDfValues);
}
}
Have you thought about State pattern? See usage example:
public class StatePatternProgram {
public static void main(String[] args) {
String example = "{uniqueKey=test20745,content={acostumbrado={tf=1,df=1},al={tf=1,df=6945},ante={tf=1,df=42},co={tf=1,df=9187},ello={tf=1,df=2},está={tf=2,df=21},falcao={tf=1,df=105},guardia={tf=1,df=2},http={tf=1,df=9893},nada={tf=1,df=24},no={tf=1,df=2493},osa={tf=1,df=429},para={tf=1,df=6382},partido={tf=1,df=50},pretorian={tf=1,df=1},que={tf=1,df=358},sebcfkeı={tf=1,df=1},su={tf=1,df=7368},t={tf=1,df=14423},tuvo={tf=1,df=3},un={tf=1,df=8511}}}";
ParseContext context = new ParseContext();
Map<String, List<Integer>> map = context.parseContent(example);
System.out.println(map);
}
}
class ParseContext {
private Map<String, List<Integer>> contentMap;
private String currentKey;
private List<Integer> currentList;
private boolean continueParsing = true;
private ParseState state = new StartParseState();
public Map<String, List<Integer>> parseContent(String content) {
StringTokenizer tokenizer = new StringTokenizer(content, "{}=,", true);
while (continueParsing) {
state.parse(tokenizer);
}
return contentMap;
}
interface ParseState {
void parse(StringTokenizer tokenizer);
}
class StartParseState implements ParseState {
#Override
public void parse(StringTokenizer tokenizer) {
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
if (!"content".equals(token)) {
continue;
}
contentMap = new LinkedHashMap<String, List<Integer>>();
tokenizer.nextToken();
tokenizer.nextToken();
state = new KeyParseState();
break;
}
}
}
class KeyParseState implements ParseState {
#Override
public void parse(StringTokenizer tokenizer) {
if (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
if (",".equals(token)) {
token = tokenizer.nextToken();
}
if ("}".equals(token)) {
state = new EndParseState();
return;
}
currentKey = token;
tokenizer.nextToken();
state = new ListParseState();
}
}
}
class ListParseState implements ParseState {
#Override
public void parse(StringTokenizer tokenizer) {
currentList = new ArrayList<Integer>();
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
if ("}".equals(token)) {
break;
}
if ("=".equals(token)) {
currentList.add(Integer.valueOf(tokenizer.nextToken()));
}
}
contentMap.put(currentKey, currentList);
state = new KeyParseState();
}
}
class EndParseState implements ParseState {
#Override
public void parse(StringTokenizer tokenizer) {
continueParsing = false;
}
}
}
This program prints:
{acostumbrado=[1, 1], al=[1, 6945], ante=[1, 42], co=[1, 9187], ello=[1, 2], está=[2, 21], falcao=[1, 105], guardia=[1, 2], http=[1, 9893], nada=[1, 24], no=[1, 2493], osa=[1, 429], para=[1, 6382], partido=[1, 50], pretorian=[1, 1], que=[1, 358], sebcfkeı=[1, 1], su=[1, 7368], t=[1, 14423], tuvo=[1, 3], un=[1, 8511]}
This solution is using regex group capturing:
private static final String SAMPLE = "{uniqueKey=test20745,content={acostumbrado={tf=1,df=1},al={tf=1,df=6945},ante={tf=1,df=42},co={tf=1,df=9187},ello={tf=1,df=2},está={tf=2,df=21},falcao={tf=1,df=105},guardia={tf=1,df=2},http={tf=1,df=9893},nada={tf=1,df=24},no={tf=1,df=2493},osa={tf=1,df=429},para={tf=1,df=6382},partido={tf=1,df=50},pretorian={tf=1,df=1},que={tf=1,df=358},sebcfkeı={tf=1,df=1},su={tf=1,df=7368},t={tf=1,df=14423},tuvo={tf=1,df=3},un={tf=1,df=8511}}}";
private static final String CONTENT = "(\\p{L}*)=\\{((tf=\\d*),(df=\\d*))\\}";
public static void main(String[] args) {
Pattern p = Pattern.compile(CONTENT);
Matcher m = p.matcher(SAMPLE);
Map<String, List<String>> result = new HashMap<String, List<String>>();
while (m.find()) {
String key = m.group(1);
List<String> values = new ArrayList<String>();
values.add(m.group(3));
values.add(m.group(4));
result.put(key, values);
}
System.out.println(result);
}
If your input pattern is unique all the time, try this
String delims = "[{},=]";
Map map = new HashMap() ;
String[] tokens = text.toString().split(delims);
for( int i=5;i<tokens.length - 7;i = i+ 7) {
map.put(tokens[i], tokens[i+2]+"->"+tokens[i+3]+","+tokens[i+4]+"->"+tokens[i+5]);
}
System.out.println(map);

Function based expression message renderer

I'm doing a simple MessageRenderer.
It's specification:
Render message based on an Context (it's a map that's contains all key/value pair parameters)
Supports simple render such as: Your username is << username >>. Assume username in the context is barcelona and the result will be Your username is Barcelona.
Supported function-like object. Example: Current time is << now() >>, now(): is an object that will returns a string of current date time. And result will be: Current time is 2011-05-30
Each parameter of function can also be templated: Current time is << now( << date_format >> ) >> . This template returns a string of current date time with format is the value of key 'date_format' retrieved from the Context. Assume date_format in Context is dd/MM/yyyy and the result will be: Current time is 30/05/2011
Each parameter of function can also be templated with a different method call: Time is << now_locale ( << getLocale() >> ). Assume that getLocale() is an function object that will be return a locale is en_US and the result will be: Time is 2011/05/30 11:20:34 PM
Template can be nested. Example: Your user name is << << username >> >>. It means, Key username has value param1, Key param1 has value is barcelona so the final result will be: Your user name is Barcelona.
My classes and interfaces:
RenderContext.java
public interface RenderContext {
public String getParameter(String key);
}
MessageRenderer.java
public interface MessageRenderer {
public String render(String s, RenderContext... context);
}
MethodExpressionEvaluator.java
// Using this class to implements the method evaluation, such as now(), now_locale()
public interface MethodExpressionEvaluator {
public String evaluate(String[] methodParams, RenderContext... context);
}
AbstractMessageRenderer.java
public abstract class AbstractMessageRenderer implements MessageRenderer {
public static final String DEFAULT_NULL = "###";
public static final String PLACEHOLDER_START_TOKEN = "<<";
public static final String PLACEHOLDER_END_TOKEN = ">>";
protected int lenPlaceholderStartToken = 0;
protected int lenPlaceholderEndToken = 0;
protected String nullToken;
protected String placeholderStartToken;
protected String placeholderEndToken;
protected boolean escape = true;
public AbstractMessageRenderer() {
placeholderStartToken = PLACEHOLDER_START_TOKEN;
placeholderEndToken = PLACEHOLDER_END_TOKEN;
lenPlaceholderStartToken = placeholderStartToken.length();
lenPlaceholderEndToken = placeholderEndToken.length();
nullToken = DEFAULT_NULL;
}
public String getNullToken() {
return nullToken;
}
public void setNullToken(String defaultNull) {
this.nullToken = defaultNull;
}
public String getPlaceholderStartToken() {
return placeholderStartToken;
}
public void setPlaceholderStartToken(String placeholderStartToken) {
this.placeholderStartToken = placeholderStartToken;
lenPlaceholderStartToken = placeholderStartToken.length();
}
public String getPlaceholderEndToken() {
return placeholderEndToken;
}
public void setPlaceholderEndToken(String placeholderEndToken) {
this.placeholderEndToken = placeholderEndToken;
lenPlaceholderEndToken = placeholderEndToken.length();
}
public boolean isEscape() {
return escape;
}
public boolean getEscape() {
return escape;
}
public void setEscape(boolean escape) {
this.escape = escape;
}
public String getParam(String key, RenderContext... context) {
if(context != null)
{
for(RenderContext param:context)
{
if(param != null)
{
String value = param.getParameter(key);
if(!StringUtil.isEmpty(value))
{
return value;
}
}
}
}
return nullToken;
}
public String render(String s, RenderContext... context) {
// handle trivial cases of empty template or no placeholders
if (s == null)
{
Log4j.app.debug("Message is null in template. Cannot render null message.");
return nullToken;
}
if (context == null)
{
Log4j.app.debug("RenderContext is null. Cannot render message with null RenderContext.");
return nullToken;
}
if (s.indexOf(placeholderStartToken) < 0)
{
return s;
}
String msg = nullToken;
try
{
// private int renderTemplate(Renderable r, String src, StringBuffer dst, String nil, int i, String[] marks, StringBuffer end,boolean escapes)
msg = doRender(s, context);
}
catch (Exception e)
{
Log4j.app.error("Exception in rendering template: " + e.getMessage(), e);
return nullToken;
}
return msg;
}
protected abstract String doRender(String s, RenderContext... context);
}
MethodExpressionRenderer.java
public class MethodExpressionRenderer extends AbstractMessageRenderer {
private boolean inSingleQuote = false;
private boolean inDoubleQuote=false;
private int placeholders;
private Stack<String> methodStack;
private String[] endTokens;
private String marker;
private List<String> methodParams;
private String prefix = "&";
public MethodExpressionRenderer() {
super();
methodStack = new Stack<String>();
marker = ",";
endTokens = new String[] { placeholderEndToken, marker, "(", ")" };
methodParams = new ArrayList<String>();
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getMarker() {
return marker;
}
public void setMarker(String marker) {
this.marker = marker;
endTokens = new String[] { placeholderEndToken, marker };
}
#Override
public void setPlaceholderEndToken(String placeholderEndToken) {
super.setPlaceholderEndToken(placeholderEndToken);
endTokens = new String[] { placeholderEndToken, marker };
}
protected String doRender(String s, RenderContext... context) {
StringBuffer sb = new StringBuffer();
try
{
renderTemplate(s, sb, nullToken, 0, endTokens, null, context);
}
catch (Exception e)
{
Log4j.app.error("Exception in rendering method expression message emplate: " + e.getMessage(), e);
return nullToken;
}
return sb.toString();
}
private int renderTemplate(String src, StringBuffer dst, String nil, int i, String[] marks, StringBuffer end, RenderContext... context) {
int len = src.length();
while (i < len)
{
char c = src.charAt(i);
if (escape)
{
if (c=='\\')
{
i++;
char ch = src.charAt(i);
if(inSingleQuote)
{
if(ch=='\'')
{
inSingleQuote=false;
}
}
else if(inDoubleQuote)
{
if(ch=='"')
{
inDoubleQuote=false;
}
}
else
{
if(ch=='\'')
{
inSingleQuote=true;
}
else if(ch=='"')
{
inDoubleQuote=true;
}
}
dst.append(ch);
i++;
continue;
}
}
if(inSingleQuote)
{
if(c=='\'')
{
inSingleQuote=false;
}
}
else if(inDoubleQuote)
{
if(c=='"')
{
inDoubleQuote=false;
}
}
else
{
if(c=='\'')
{
inSingleQuote=true;
}
else if(c=='"')
{
inDoubleQuote=true;
}
}
// check for end marker
if (marks != null && !inSingleQuote && !inDoubleQuote)
{
for (int m = 0; m < marks.length; m++)
{
// If one of markers found
if (src.regionMatches(i, marks[m], 0, marks[m].length()))
{
// return marker if required
if (end != null)
{
end.append(marks[m]);
}
return i+marks[m].length();
}
}
}
// check for start of placeholder
if (src.regionMatches(i, placeholderStartToken, i, lenPlaceholderStartToken))
{
synchronized(this)
{
++placeholders;
}
i = renderPlaceholder(src, dst, nil, i, new ArrayList<String>(), context);
continue;
}
// just add plain character
if(c != '\'' && c!= '"')
{
dst.append(c);
}
i++;
}
return i;
}
private int renderPlaceholder(String src, StringBuffer dst, String nil, int i, List<String> params, RenderContext... context){
StringBuffer token = new StringBuffer(); // placeholder token
StringBuffer end = new StringBuffer(); // placeholder end marker
String value;
i = renderTemplate(src, token, nil, i+lenPlaceholderStartToken, endTokens, end);
String sToken = token.toString().trim();
String sEnd = end.toString().trim();
boolean isFunction = sEnd.equals("(");
// This is method name
if(isFunction && placeholders > methodStack.size())
{ // Method
synchronized(this)
{
methodStack.push(sToken); // put method into stack
}
}
else if(!isFunction && (methodStack.size()==0) && sEnd.equals(placeholderEndToken)) // Single template param such as <<param>>
{
value = getParam(sToken, context);
if(value != null)
{
if(value.trim().startsWith(placeholderStartToken))
{
value = render(src, context);
}
dst.append(value);
return i;
}
}
// TODO: Process method parameters to invoke
//.... ?????????
// Found end method token ')'
// Pop method out of stack to invoke
if ( (methodStack.size() >0) && (sEnd.length() == 0 || sEnd.equals(")")))
{
String method = null;
synchronized(this)
{
// Pop method out of stack to invoke
method = methodStack.pop();
--placeholders;
dst.append(invokeMethodEvaluator(method, methodParams.toArray(new String[0]), context));
methodParams.clear();
}
}
return i;
}
// Currently this method just implement to test so it just printout the method name
// and its parameter
// We can register MethodExpressionEvaluator to process
protected String invokeMethodEvaluator(String method, String[] params, RenderContext... context){
StringBuffer result = new StringBuffer();
result.append("[ ")
.append(method)
.append(" ( ");
if(params != null)
{
for(int i=0; i<params.length; i++)
{
result.append(params[i]);
if(i != params.length-1)
{
result.append(" , ");
}
}
}
result.append(" ) ")
.append(" ] ");
return result.toString();
}
}
We can easily register more method to the renderer to invoke. Each method will be an object and can be reused. But I'm in trouble how to resolve the nested method parameter. Can anyone give me an advice how we can process nested template of method parameter to invoke??? The line has TODO. Will my code in on the right way???
When you evaluate something like << count( << getTransId() >> ) >> you can either:
perform direct-evaluation as you parse, and push each function onto a stack, so that once you've evaluated getTransId() you pop the stack and use the return value (from the stack) as an argument for count(), or
you can build a parse tree to represent all the function calls that will be made, and then evaluate your parse tree after building it. (Building a tree probably doesn't buy you anything; since you're writing a template engine there is probably no high-level tree operation 'optimizations' that you could perform.)
An excellent little book I really enjoyed was Language Implementation Patterns by Parr. He walks through building simple to complex languages, and covers decisions like this in some depth. (Yes, he uses the ANTLR parser generator throughout, but your code looks like you're familiar enough with hand-generated parsers that different tools won't be a distraction for you.)
I found the bug and fixed it.
This is my new source:
// AbstractMethodExpressionRenderer.java
public class AbstractMethodExpressionRenderer extends AbstractMessageRenderer {
private boolean inSingleQuote = false;
private boolean inDoubleQuote=false;
private Stack<MethodExpressionDescriptor> functionStack;
private String[] endTokens;
private String marker;
private String prefix = "~";
public AbstractMethodExpressionRenderer() {
super();
functionStack = new Stack<MethodExpressionDescriptor>();
marker = ",";
endTokens = new String[] { placeholderEndToken, "(", ")", };
}
private class MethodExpressionDescriptor {
public List<String> params;
public String function;
public MethodExpressionDescriptor() {
params = new ArrayList<String>();
}
public MethodExpressionDescriptor(String name) {
this();
this.function = name;
}
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getMarker() {
return marker;
}
public void setMarker(String marker) {
this.marker = marker;
endTokens = new String[] { placeholderEndToken, marker };
}
#Override
public void setPlaceholderEndToken(String placeholderEndToken) {
super.setPlaceholderEndToken(placeholderEndToken);
endTokens = new String[] { placeholderEndToken, marker };
}
protected String doRender(String s, RenderContext... context) {
StringBuffer sb = new StringBuffer();
try
{
renderTemplate(s, sb, nullToken, 0, endTokens, null, context);
}
catch (Exception e)
{
Log4j.app.error("Exception in rendering method expression message emplate: " + e.getMessage(), e);
return nullToken;
}
return sb.toString();
}
private int renderTemplate(String src, StringBuffer dst, String nil, int i, String[] marks, StringBuffer end, RenderContext... context) {
int len = src.length();
while (i < len)
{
char c = src.charAt(i);
if (escape)
{
if (c=='\\')
{
i++;
char ch = src.charAt(i);
if(inSingleQuote)
{
if(ch=='\'')
{
inSingleQuote=false;
}
}
else if(inDoubleQuote)
{
if(ch=='"')
{
inDoubleQuote=false;
}
}
else
{
if(ch=='\'')
{
inSingleQuote=true;
}
else if(ch=='"')
{
inDoubleQuote=true;
}
}
dst.append(ch);
i++;
continue;
}
}
if(inSingleQuote)
{
if(c=='\'')
{
inSingleQuote=false;
}
}
else if(inDoubleQuote)
{
if(c=='"')
{
inDoubleQuote=false;
}
}
else
{
if(c=='\'')
{
inSingleQuote=true;
}
else if(c=='"')
{
inDoubleQuote=true;
}
}
// check for end marker
if (marks != null && !inSingleQuote && !inDoubleQuote)
{
for (int m = 0; m < marks.length; m++)
{
// If one of markers found
if (src.regionMatches(i, marks[m], 0, marks[m].length()))
{
// return marker if required
if (end != null)
{
end.append(marks[m]);
}
return i+marks[m].length();
}
}
}
// check for start of placeholder
if (src.regionMatches(i, placeholderStartToken, 0, lenPlaceholderStartToken))
{
i = renderPlaceholder(src, dst, nil, i, new ArrayList<String>(), context);
continue;
}
// just add plain character
if(c != '\'' && c!= '"')
{
dst.append(c);
}
i++;
}
return i;
}
/**
* Render a placeholder as follows:
*
* <<key>>: Simple render, key value map
* <<function(<<param1>>, <<param2>>)>> : Function object render
*
* #param src
* #param dst
* #param nil
* #param i
* #param params
* #param context
* #return
*/
private int renderPlaceholder(String src, StringBuffer dst, String nil, int i, List<String> params, RenderContext... context){
StringBuffer token = new StringBuffer(); // placeholder token
StringBuffer end = new StringBuffer(); // placeholder end marker
String value = null;
// Simple key
i = renderTemplate(src, token, nil, i+lenPlaceholderStartToken, endTokens, end, context);
String sToken = token.toString().trim();
String sEnd = end.toString().trim();
// This is method name
if(sEnd.equals("("))
{ // Method
functionStack.add(new MethodExpressionDescriptor(sToken));
}
else // Try to resolve value
{
if(sToken.startsWith(placeholderStartToken))
{
value = render(sToken, context);
}
else if(sToken.startsWith(prefix))
{
if(functionStack.size() > 0)
{
functionStack.peek().params.add(sToken.substring(1));
}
return i;
}
else
{
value = getParam(sToken, context);
}
}
if (sEnd.length() == 0 || sEnd.equals(placeholderEndToken))
{
// No method found but found the end of placeholder token
if(functionStack.size() == 0)
{
if(value != null)
{
dst.append(value);
}
else
{
dst.append(nil);
}
}
else
{
functionStack.peek().params.add(value);
}
}
else
{
if(value != null)
{
value = value.trim();
}
if(end.substring(0, 1).equals("(") ||
end.substring(0, 1).equals(marker))
{
// right hand side is remainder of placeholder
StringBuffer tmp = new StringBuffer();
end = new StringBuffer();
i = renderTemplate(src, tmp, nil, i, endTokens, end, context);
}
if(end.substring(0, 1).equals(")"))
{
if ( functionStack.size() > 0 )
{
// Pop method out of stack to invoke
MethodExpressionDescriptor descriptor = functionStack.pop();
if(functionStack.size() > 0 )
{
functionStack.peek().params.add(invokeMethodEvaluator(descriptor.function, descriptor.params.toArray(new String[0]), context));
}
else
{
dst.append(invokeMethodEvaluator(descriptor.function, descriptor.params.toArray(new String[0]), context));
}
end = new StringBuffer();
StringBuffer tmp = new StringBuffer();
i = renderTemplate(src, tmp, nil, i, endTokens, end, context);
}
}
}
return i;
}
protected String invokeMethodEvaluator(String method, String[] params, RenderContext... context){
StringBuffer result = new StringBuffer();
result.append("[ ")
.append(method)
.append(" ( ");
if(params != null)
{
for(int i=0; i<params.length; i++)
{
result.append(params[i]);
if(i != params.length-1)
{
result.append(" , ");
}
}
}
result.append(" ) ")
.append(" ] ");
return result.toString();
}
}

Categories

Resources