I am making a calculator that uses a linked list. It mostly works, but in one case it gives me an error. To declare a constant you use "=:" =:constantname to declare a variable you use "=" so =variablename
My error comes when the input is like this:
java P7.java -postfix
3
4
=:bob
8
=test
4
bob
when you type bob it gives:
java.lang.NullPointerException
at cStack.getcon(P7.java:403)
at P7.process(P7.java:208)
at P7.main(P7.java:36)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at jdk.compiler/com.sun.tools.javac.launcher.Main.execute(Main.java:415)
at jdk.compiler/com.sun.tools.javac.launcher.Main.run(Main.java:192)
at jdk.compiler/com.sun.tools.javac.launcher.Main.main(Main.java:132)
I am unsure how to fix this... Here is my code:
import java.util.*;
public class P7 {
static Scanner scan = new Scanner(System.in);
static int cnt = 0;
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("ERROR: No arguments!");
usage();
}
else if (args[0].equals("--help")) {
usage();
}
else if (args[0].equals("-postfix")) {
//start the processor method
try {
process();
}
catch(NullPointerException e) {
System.out.println(e.toString());
e.printStackTrace();
}
}
else {
System.out.println("Did not recognize.");
usage();
}
}
public static void process() {
Stack stack = new Stack();
cStack cstack = new cStack();
double temp = 0.0;
double val = 0.0; //latest value
double temp0 = 0.0;
double temp1 = 0.0;
double temp2 = 0.0;
double temp3 = 0.0;
double tempcon = 0.0;
while (scan.hasNext()) {
if (scan.hasNextDouble()) { //checks if double
val = scan.nextDouble();
stack.push(val);
//pushes value on stack
}
else {
String s = scan.next();
if (s.equals("+")) {
stack.push(stack.pop() + stack.pop());
}
else if (s.equals("-")) {
temp = stack.pop();
stack.push(stack.pop() - temp);
}
else if (s.equals("*")) {
stack.push(stack.pop() * stack.pop());
}
else if (s.equals("~")) {
stack.push(stack.pop() * -1);
}
else if (s.equals("swap")) {
temp0 = stack.pop();
temp1 = stack.pop();
stack.push(temp0);
stack.push(temp1);
}
else if (s.equals("copy")) {
temp2 = stack.pop();
stack.push(temp2);
stack.push(temp2);
}
else if (s.equals("/")) {
temp = stack.pop();
if (temp == 0.0) {
System.out.println("ERROR: Can't divide by zero. Exiting...");
System.exit(1);
}
else {
stack.push(stack.pop() / temp);
}
}
else if (s.equals("'")) {
stack.push(1.0 / stack.pop());
}
else if (s.equals("**")) {
temp3 = stack.pop();
stack.push(Math.pow(stack.pop(), temp3));
}
else if (s.equals("peek")) {
System.out.println(stack.peek());
}
else if (s.equals("dump")) {
stack.dump();
}
else if (s.equals("=")) {
if (stack.isEmpty()) {
System.out.println("Stack underflow, not enough values. Exiting.");
System.exit(0);
}
else {
System.out.println("Result = " + stack.pop() + ".");
System.out.println("There are " + stack.cnt() + " values remaining on the stack.");
System.exit(0);
}
}
/*else if (cstack.isValidCon(s)) {
String cName = s.substring(2);
if (cstack.constantExists(cName)) {
System.out.println("Constant name already exists.");
}
else {
tempcon = stack.pop();
cstack.setConstant(tempcon, cName, cstack.isValidCon(cName));
stack.push(tempcon);
}
}
else if (s.substring(0, 2).equals("=:") && !cstack.isValidCon(s)) {
System.out.println("Invalid constant name");
}
*/
else if (s.substring(0, 2).equals("=:") && (s.length() > 2)) {
String cName = s.substring(2);
if (!cstack.isValidCon(s)) {
System.out.println("Invalid constant name.");
}
else if (cstack.checkConName(cName) == true && cstack.isConOrVar(cName) == true) {
System.out.println("Constant name already in use.");
}
else {
cstack.setConstant(stack.peek(), cName, true);
}
}
else if (s.substring(0, 1).equals("=") && (s.length() > 1)) {
String vName = s.substring(1);
if (cstack.isValidVariable(s) == true) {
if (cstack.checkConName(vName) == true) {
System.out.println("Constant with name already exists.");
}
else {
cstack.setConstant(stack.peek(), vName, false);
}
}
else {
System.out.println("Didn't recognize input. Exiting.");
System.exit(0);
}
}
else if (cstack.checkConName(s) == true) {
stack.push(cstack.getcon(s));
}
else if (cstack.checkVarName(s) == true) {
stack.push(cstack.getVar(s));
}
else if (cstack.checkVarName(s) == false || cstack.checkConName(s) == false) {
System.out.println("Didn't recognize input. Exiting.");
System.exit(0);
}
else {
System.out.println("Didn't recognize input. Exiting.");
System.exit(1);
}
}
}
}
public static void usage() {
System.out.println("Usage: P3");
System.out.println("\"P3 --help\" to display this usage material.");
System.out.println("\"\"P3 -postfix\" to accept input from standard input as a sequence");
System.out.println("of numbers and operators. The numbers read are stored on a");
System.out.println("stack until needed. When an operator is read, the required");
System.out.println("operands are popped from the stack and used to perform the");
System.out.println("calculation, with the result placed on the stack. Valid");
System.out.println("operators are +, -, *, /, ~, ', *** swap, peek, dump, and copy which are performed as");
System.out.println("addition, subtraction, multiplication, division, negation, swapping, and copying");
System.out.println("respectively, and as described below. An additional");
System.out.println("operator is =, which indicates that the value at the top of");
System.out.println("the stack is popped from the stack and displayed along with");
System.out.println("the number of values remaining on the stack.");
System.out.println("Stack underflows generate an error message and halt the program.");
System.out.println("Stack operations are performed as indicated");
System.out.println("here.");
System.out.println("+ : push(pop() + pop());");
System.out.println("- : temp = pop(); push(pop() – temp;");
System.out.println("* : push(pop() * pop());");
System.out.println("/ : temp = pop(); push(pop() / temp;");
System.out.println("= :");
System.out.println("~ : Negation. Changes the sign of the top of the stack.");
System.out.println("' : Inversion. push(1.0 / pop())");
System.out.println("** : Exponentiation. temp = pop(); push(Math.pow(pop(), temp))");
System.out.println("peek : display the current top-of-stack value.");
System.out.println("dump : display the complete stack contents, one per line, starting with top-of-stack.");
System.out.println("swap : temp0 = pop(); temp1 = pop(); push(temp0); push(temp1)");
System.out.println("copy : temp = pop(); push(temp); push(temp);");
}
}
class cNode {
double cData;
double vData;
cNode cNext;
String conName;
String varName;
boolean isConstant;
}
class cStack {
private cNode cTop;
public cStack() {
this.cTop = null;
}
public boolean iscEmpty()
{
return cTop == null;
}
public void setConstant(double cval, String name, boolean isCon) {
cNode cnode = new cNode();
if (isCon == true) {
cnode.isConstant = true;
cnode.cData = cval;
cnode.conName = name;
}
else {
cnode.isConstant = false;
cnode.vData = cval;
cnode.varName = name;
}
cnode.cNext = cTop;
cTop = cnode;
}
public boolean isConOrVar(String name) {
boolean isACon = false;
cNode temp2cNode = cTop;
while (cTop != null) {
if (name.equals(cTop.conName) && cTop.isConstant == true) {
isACon = true;
break;
}
else if (name.equals(cTop.conName) && cTop.isConstant == false) {
isACon = false;
cTop = cTop.cNext;
}
else {
cTop = cTop.cNext;
}
}
cTop = temp2cNode;
return isACon;
}
public boolean checkConName(String a) {
boolean found = false;
String b;
cNode temp1cNode = cTop;
while (cTop != null) {
if (a.equals(cTop.conName)) {
found = true;
break;
}
else {
cTop = (cTop).cNext;
}
}
cTop = temp1cNode;
return found;
}
public boolean checkVarName(String a) {
boolean found1 = false;
String b;
cNode tempvNode = cTop;
while (cTop != null) {
if (a.equals(cTop.varName)) {
found1 = true;
break;
}
else {
cTop = cTop.cNext;
}
}
cTop = tempvNode;
return found1;
}
public boolean isValidVariable(String varName) {
boolean isVar = false;
int i;
if ((varName.length() > 1) && varName.substring(0, 1).equals("=")) {
for (i = 1; i < varName.length(); ++i) {
char c = varName.charAt(i);
if (Character.isLetterOrDigit(c)) {
isVar = true;
}
else {
isVar = false;
break;
}
}
}
return isVar;
}
public double getcon(String name) {
boolean found = false;
cNode tempcNode = cTop;
double retval = 0.0;
while (cTop != null) {
if (cTop.conName.compareTo(name) == 0) {
retval = cTop.cData;
found = true;
break;
}
else {
cTop = (cTop).cNext;
}
}
cTop = tempcNode;
return retval;
}
public double getVar(String name) {
boolean varFound = false;
cNode tempVarNode = cTop;
double retCon = 0.0;
while (cTop != null) {
if (cTop.varName.compareTo(name) == 0) {
retCon = cTop.vData;
varFound = true;
break;
}
else {
cTop = cTop.cNext;
}
}
cTop = tempVarNode;
return retCon;
}
public boolean constantExists(String name) {
boolean exists = false;
cNode tempNode = cTop;
while (cTop != null && !exists) {
if (cTop.conName.equals(name)) {
exists = true;
break;
}
else {
cTop = (cTop).cNext;
}
}
cTop = tempNode;
return exists;
}
public boolean isValidCon(String conName) {
boolean retbool = false;
int i = 0;
String check = conName.substring(2);
if (conName.length() > 2) {
if (conName.substring(0, 2).equals("=:") && conName.length() > 2 && conName.substring(2).length() >= 1) {
for (i = 0; i < check.length(); ++i) {
char c = check.charAt(i);
if (Character.isLetterOrDigit(c)) {
retbool = true;
}
else {
retbool = false;
}
}
}
}
else {
return false;
}
return retbool;
}
}
class Node
{
double data;
Node next;
};
class Stack
{
private Node top;
public Stack() {
this.top = null;
}
public void dump() {
Node tempNode = top;
while (!isEmpty()) {
System.out.println(top.data);
top = (top).next;
}
top = tempNode;
}
public void push(double x)
{
Node node = new Node();
if (node == null)
{
System.out.print("Overflow");
return;
}
node.data = x;
node.next = top;
top = node;
}
public boolean isEmpty()
{
return top == null;
}
public double peek()
{
if (!isEmpty()) {
return top.data;
}
else {
System.out.println("Stack is empty");
return -1;
}
}
public double pop()
{
// check for stack underflow
if (isEmpty()) {
System.out.println("Stack underflow");
}
if (top == null)
{
System.out.print("Stack Underflow");
}
double a = top.data;
top = (top).next;
return a;
}
public int cnt() {
Node tempN = top;
int cnt = 0;
while (!isEmpty()) {
++cnt;
top = (top).next;
}
top = tempN;
return cnt;
}
}
```