//Simple Syntax Checker - Program that uses a stack to check that an expression
//contains matching  () [] or {}
//By www.neiljohan.com

import java.io.*;

public class SyntaxCheck
{
    static String ExpressionString;
    static Stack St = new StackImpl();

    public static void main(String[] pArgs) throws Exception
        {
            String ErrorChar;
            boolean Errors=false;
            String BigErrorMessage=""; //Composite of all Error Messages
            String NewError;           //Each individual error
            
            ExpressionString = NeilClass.GetInputString("Type in an expression ");
            int ExpressionLength = ExpressionString.length();
            
            for (int i=0; i<ExpressionLength; i++){
                String tChar = ExpressionString.substring(i,i+1);

                if (ExpressionMatch(tChar)){
                        //a matching pair has been found, remove from stack
                    St.pop();
                }
                else if (SymbolChar(tChar)){
                        //add symbol to stack
                    St.push(tChar);
                }
            }
            
                //Get Errors and reverse their order so they make more sence
            while (! St.isEmpty()){
                ErrorChar = (String)St.topAndPop();
                NewError = "A " + ErrorChar + " was found without a matching " + ExpOp(ErrorChar) + '\n';
                BigErrorMessage = NewError + BigErrorMessage;
                Errors=true;
            }

            if (!Errors)
                System.out.println("No Errors were Found");
            else
                System.out.println(BigErrorMessage);
            
        }


    public static boolean ExpressionMatch(String tChar) throws Exception
        {
            boolean returnValue;
            
            if (St.isEmpty()){
                returnValue=false;
            }else{

                if (   St.top().equals("(") && tChar.equals(")")
                    || St.top().equals("[") && tChar.equals("]")
                    || St.top().equals("{") && tChar.equals("}"))
                {
                    returnValue = true;
                }
                else{
                    returnValue = false;
                }
            }

            return returnValue;
        }


        //returns true is Sy is one of (,),[,],{ or }
    public static boolean SymbolChar(String Sy)
        {
            boolean returnValue = false;
            
            if (Sy.equals("(") || Sy.equals(")") || Sy.equals("[") || Sy.equals("]") || Sy.equals("{") || Sy.equals("}"))
                returnValue = true;

            return returnValue;
        }


    public static String ExpOp(String tChar)
        {
            String returnValue="";

            if (tChar.equals("(")) { returnValue=")"; }
            if (tChar.equals(")")) { returnValue="("; }
            if (tChar.equals("[")) { returnValue="]"; }
            if (tChar.equals("]")) { returnValue="["; }
            if (tChar.equals("{")) { returnValue="}"; }
            if (tChar.equals("}")) { returnValue="{"; }
            return returnValue;
        }
}

