/*
* A Java program can have the following type of delimiters: {, }, (, ), [,
* and ]. In a correct Java program, these delimiters must be properly nested.
* Think of each left delimiter {, (, and [ as opening a scope, and think of
* each right delimiter }, ), and ] as closing a scope opened by a corresponding
* left delimiter. A string of characters containing these delimiters has proper
* nesting of delimiters if each scope that is opened is eventually closed, and
* the scopes are opened and closed in a last-opened-first-closed fashion.
* Write a program, using your own stack and/or queue code, that reads a file
* containing Java source code and checks it for proper nesting of delimiters.
* Your program should read the source code from the file and print it to the
* screen. If the file is properly nested, all of it is printed to the screen
* and a message is printed that the file is properly nested. If the file is
* not properly nested, then copying of the file to the screen stops as soon
* as improper nesting is detected, and your program prints a message that the
* file has errors. To simplify your task, you may assume these delimiters do
* not appear inside of comments and string literals, and that they do not
* appear in the program as character literals--i.e. only appear as "keywords".
*
* Name: Phillip Vinson
* Project: Checking Code text file for proper syntax braces
* Date: 03/12/2013
*/
package hw4vinson;
import java.io.*;
import java.util.*;
//Stack class, using linked list format
public class HW4Vinson
{
public class Node
{
String value;
Node next;
Node(String val, Node n)
{
value = val;
next = n;
}
}
public Node top = null; //Top of stack
//checks to see if the stack is empty
public boolean empty()
{
return top == null;
}
//adds a node/element to the stack
public void push(String s)
{
top = new Node(s, top);
}
//removes the head node/element from the stack, throws error if stack is empty
public String pop()
{
if (empty())
{
throw new EmptyStackException();
}
else
{
String retValue = top.value;
top = top.next;
return retValue;
}
}
//returns the head node/element from the stack, throws an error if empty
public String peek()
{
if (empty())
{
throw new EmptyStackException();
}
else
{
return top.value;
}
}
public String toString()
{
StringBuilder sBuilder = new StringBuilder();
Node p = top;
while(p != null)
{
sBuilder.append(p.value);
p = p.next;
if (p != null)
{
sBuilder.append("\n");
}
}
return sBuilder.toString();
}
//Main program
public static void main(String[] args)
{
String temp; //store syntax
String fileName; //var to hold user input from keyboard
Scanner kb = new Scanner(System.in); //Get user input
System.out.println("Enter a file to be read: (EX: file.txt)");
fileName = kb.nextLine(); //Store user input from keyboard
//Create a stack/linked list
HW4Vinson st = new HW4Vinson();
//What To Do:
//1. Read in a text file and store all instances of {, [, (
// into the stack
//2. Reread and print the text file, but compare the stack contents with
// each }, ], ) and make sure it matches.
//3. For instance if you read in
// {, {, (, { then your pop should match with }, ), }, }
//4. If it does not then stop the text print at the instance of bad read
// and display an error message stating the error and which delimeter
// is missing.
//5. If no errors are found the entire text file should print
try
{
//Open user designated file
FileInputStream fstream = new FileInputStream(fileName);
//Prepare files
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
//Read file line by line
while((strLine = br.readLine()) != null)
{
//check for symbol matches on each line and push onto stack
if("{".equals(strLine) || "[".equals(strLine) || "(".equals(strLine))
{
//push matching symbols onto our st stack
if ("{".equals(strLine))
{
temp = strLine;
st.push(temp);
}
else if ("[".equals(strLine))
{
temp = strLine;
st.push(temp);
}
if ("(".equals(strLine))
{
temp = strLine;
st.push(temp);
}
}
}
//close the input stream
in.close();
strLine.toString();
}
catch(Exception e)
{
System.err.println("Error: " + e.getMessage());
}
//Print out all the elements being stored in the stack for
//error checking
System.out.println("\nElements in stack:");
System.out.println(st);
System.out.println("\n\n"); //skip a few lines
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
//Read file again to check for any erros in syntax
try
{
//reopen user designated file
FileInputStream fstream = new FileInputStream(fileName);
//Prepare files
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
//Read file line by line
while((strLine = br.readLine()) != null)
{
System.out.println(strLine); //print out the code being stored
//check for symbol match
if("}".equals(strLine))
{
String holder = st.pop(); //pop and store head element
//if symbol coming off stack matches the improper syntax
//throw error message
if("(".equals(holder))
{
//throw an error
System.out.println("Error Missing Syntax");
}
else if("[".equals(holder))
{
//throw an error
System.out.println("Error Missing Syntax");
}
}
//check for symbol match on "]"
else if("]".equals(strLine))
{
String holder = st.pop(); //pop and store head element
//if symbol coming off stack matches the improper syntax
//throw error message
if("{".equals(holder))
{
//throw an error
System.out.println("Error Missing Syntax");
}
else if("(".equals(holder))
{
//throw an error
System.out.println("Error Missing Syntax");
}
}
//check for symbol match
else if(")".equals(strLine))
{
String holder = st.pop(); //pop and store head element
//if symbol coming off stack matches the improper syntax
//throw error message
if("{".equals(holder))
{
//throw an error
System.out.println("Error Missing Syntax");
}
else if("[".equals(holder))
{
//throw an error
System.out.println("Error Missing Syntax");
}
}
}
//close the input stream
in.close();
}
catch(Exception e)
{
System.err.println("Error: " + e.getMessage());
}
}
}
/*
This is the file i'm using to test code:
while (x == 32)
{
s = 34;
if (s == 34)
{
s = s-1;
}
}
running the above text file i get the output:
run:
Enter a file to be read: (EX: file.txt)
correctFile.txt
Error: null
Elements in stack:
{
while (x == 32)
{
s = 34;
if (s == 34)
{
s = s-1;
}
}
BUILD SUCCESSFUL (total time: 4 seconds)
Obviously this is not correct, it should print out all the values being stored
in the stack first (apparently none based off the run), and then go through
and perform a syntax check,if no errors are found it will just print the code
to the screen (like it did)
*/