Creating condition statement with ANTLR 4 and Java - java

So I'm trying to build myself my own programming language with swedish syntax(most for fun) and I have successfully managed to create variables and do some basic arithmetic on them. Moving on to do some conditional statements, I ran into some trouble. To start off, here is my (relevant) code:
SPL.g4 //My grammar file.
grammar SPL;
file
:code
;
code
:statement ';' code
;
statement
:print
|assign
|decl
|loop
|condition
;
//Declares variable
decl
:'variabel' ID
;
//Assign variable with an expression.
assign
:ID '=' expr
;
//A general expression.
expr
:'-' expr #unaryMinusExpr
|'!' expr #notExpr
|expr op=('/' | '*') expr #multiplicationExpr
|expr op=('+' | '-') expr #additiveExpr
|expr op=('<=' |'>=' | '<' | '>') expr #relationalExpr
|expr op=('=' | '!=') expr #equalityExpr
|expr 'OCH' expr #andExpr
|expr 'ELLER' expr #orExpr
|atomExpr #atom
;
//An atomic expression, more or less just a variable.
atomExpr
:ID
|INT
|'(' expr ')'
;
ID:('a'..'z')+ ;
STR:([a-zA-Z_] [a-zA-Z_0-9]*)+ ;
INT:([0-9]+)+ ;
WS: [ \n\t\r]+ -> skip ;
//Prints expr to the console
print
: 'skriv' expr
;
//Supposed to be some kind of loop and condition WORK IN PROGRESS!
condition
:'om' conditionCode ('annars om' conditionCode)* ('annars' otherBlock)?
;
conditionCode
: expr otherBlock
;
otherBlock
:'{'file'}'
| code
;
loop
:'när' expr ';'
;
Interpreter
import grammar.SPLBaseListener;
import grammar.SPLParser;
import org.antlr.v4.runtime.Token;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
/**
* Interpretes the code genereated by the parser.
* Overrides methods from the TestBaseListener so we can decide what happends.
* Created by student on 2017-01-27.
*
*/
public class Interpreter extends SPLBaseListener {
/**
* A class that holds a value. Used for storing key & value pairs in a hashmap.
*/
private static class Variable {
int val;
public Variable(int val) {
this.val = val;
}
}
private final HashMap<String, Variable> vars = new HashMap<>(); //Stores keys and values.
private Stack<Integer> exprVal = new Stack<>(); //Stores the current values.
private Stack<Boolean> conditionBooleans = new Stack<>(); //Stores the evaluated conditions
/**
* Returns a variable from the hashmap given the variable's name.
*
* #param tok
* #return
*/
private Variable getVar(Token tok) {
String name = tok.getText();
Variable v = vars.get(name);
if (v == null) {
error(tok.getLine(), "undefined " + name);
return new Variable(0); // avoid null pointer exception
} else {
return v;
}
}
/**
* When entering a declaration of a variable, we put it in the hashtable with it's name
* and a initial value of 0.
*
* #param ctx
*/
#Override
public void enterDecl(SPLParser.DeclContext ctx) {
String name = ctx.ID().getText();
Variable old = vars.put(name, new Variable(0));
if (old != null) {
error(ctx.ID().getSymbol().getLine(), "redefined " + name);
}
}
/**
* When we have exited the assignment, the variable already stored, get's the
* value that the stack is holdning.
*
* #param ctx
*/
#Override
public void exitAssign(SPLParser.AssignContext ctx) {
getVar(ctx.ID().getSymbol()).val = exprVal.pop();
}
/**
* If + add two numbers top of stack else substract them and add them back.
*
* #param ctx
*/
#Override public void exitAdditiveExpr(SPLParser.AdditiveExprContext ctx) {
String op = ctx.op.getText();
if(op.equals("+")){
exprVal.push(exprVal.pop() + exprVal.pop());
}else{ // '-'
int top = (exprVal.pop());
int second = (exprVal.pop());
exprVal.push(second - top);
}
}
/**
* If * multiplty two numbers top of stack else divide them and add them back.
*
* #param ctx
*/
#Override public void exitMultiplicationExpr(SPLParser.MultiplicationExprContext ctx) {
String op = ctx.op.getText();
if(op.equals("*")){
exprVal.push(exprVal.pop() * exprVal.pop());
}else{// '/'
int top = (exprVal.pop());
int second = (exprVal.pop());
exprVal.push(second / top);
}
}
/**
* Takes the two top elements from the stack and compares them.
* #param ctx
*/
#Override public void exitRelationalExpr(SPLParser.RelationalExprContext ctx) {
System.out.println("Im here checking relation! " + exprVal.size());
int top = (exprVal.pop());
int second = (exprVal.pop());
switch (ctx.op.getText()) {
case "<=":
System.out.println("<=");
if(top<=second)
conditionBooleans.push(true);
break;
case ">=":
System.out.println(">=");
if(top>=second)
conditionBooleans.push(true);
break;
case "<":
System.out.println("<");
if(top<second)
conditionBooleans.push(true);
break;
case ">":
System.out.println(">");
if(top>second)
conditionBooleans.push(true);
break;
default:
conditionBooleans.push(false);
}
}
/**
* Decides what codeblock to run. TODO DOES NOT WORK!
* #param ctx
*/
#Override public void enterCondition(SPLParser.ConditionContext ctx) {
System.out.println("\n CONDITION ENTERED------------------------------------------------------------------");
System.out.println(ctx.conditionCode().get(0).getText());
}
/**
* When a atomexpression is declared in code
* and if it's not null it will be pushed onto the stack.
*
* #param ctx
*/
#Override
public void enterAtomExpr(SPLParser.AtomExprContext ctx) {
if (ctx.ID() != null) {
exprVal.push(getVar(ctx.ID().getSymbol()).val);
} else if (ctx.INT() != null) {
exprVal.push(Integer.parseInt(ctx.INT().getText()));
}
}
/**
* Prints the value of exprValue.
*
* #param ctx
*/
#Override
public void exitPrint(SPLParser.PrintContext ctx) {
System.out.println("Utskrift:");
System.out.println(exprVal.pop());//Pop off the top value and print it.
}
/**
* Prints error message to the console.
*
* #param line
* #param msg
*/
private void error(int line, String msg) {
System.err.println(":" + line + ": " + msg);
}
}
test.t //the test file I'm using
variabel a;
variabel b;
a = 10;
b = 20;
a = a + b;
om a < b{
skriv a;
};
So when the interpreter reaches the if statement, that is first getting evaluated, and then it goes on to evaluate the expression. I am not sure of the order here and what to do. I believe I should save the value of the condition so I can retrieve it later on and decide on which codeblock to run. But I'm totaly lost on where to even begin.

Related

JAVA Evaluating postfix expressions -- unable to throw empty or invalid expressions

I'm writing a program that will evaluate a postfix expression and print both the original expression and the result. But I want to account for the validity of the expression as well. For this, I've written two exception classes -- one for an empty collection and one for invalid postfix expressions. But my code is getting stuck somewhere; my output evaluates the first expression correctly, but then only prints the original postfix expressions after that. I believe the problem is perhaps coming from my PostfixEvaluator class (see below), where I attempt to check for the size of my stack in the evaluate method. When commented out, my postfix expressions evaluate (albeit without the exceptions being caught, but still, it's something).
My code and resulting output:
Postfix Tester:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class PostfixTester
{
/**
* Reads and evaluates multiple postfix expressions.
* #throws FileNotFoundException
*/
public static void main(String[] args) throws FileNotFoundException{
String expression, again;
int result;
//Scanner in = new Scanner(System.in);
Scanner in = new Scanner(new File("test.txt"));
PostfixEvaluator evaluator = new PostfixEvaluator();
while(in.hasNext()){
expression = in.nextLine();
System.out.println(expression);
try{
result = evaluator.evaluate(expression);
System.out.println("The result is: " + result);
}
catch(EmptyCollectionException e){
e.getMessage();
}
catch(InvalidPostfixExpressionException e){
e.getMessage();
}
System.out.println();
}
}
}
Postfix Evaluator:
import java.util.Stack;
import java.util.Scanner;
public class PostfixEvaluator
{
private final static char ADD = '+';
private final static char SUBTRACT = '-';
private final static char MULTIPLY = '*';
private final static char DIVIDE = '/';
private ArrayStack<Integer> stack;
/**
* Sets up this evalutor by creating a new stack.
*/
public PostfixEvaluator()
{
stack = new ArrayStack<Integer>();
}
/**
* Evaluates the specified postfix expression. If an operand is
* encountered, it is pushed onto the stack. If an operator is
* encountered, two operands are popped, the operation is
* evaluated, and the result is pushed onto the stack.
* #param expr string representation of a postfix expression
* #return value of the given expression
*/
public int evaluate(String expr)
{
int op1, op2, result = 0;
String token;
Scanner parser = new Scanner(expr);
while (parser.hasNext())
{
token = parser.next();
if (isOperator(token))
{
op2 = (stack.pop()).intValue();
op1 = (stack.pop()).intValue();
result = evaluateSingleOperator(token.charAt(0), op1, op2);
stack.push(new Integer(result));
}
else
stack.push(new Integer(Integer.parseInt(token)));
}
if(stack.size() != 1){
throw new InvalidPostfixExpressionException();
}
return result;
}
/**
* Determines if the specified token is an operator.
* #param token the token to be evaluated
* #return true if token is operator
*/
private boolean isOperator(String token)
{
return ( token.equals("+") || token.equals("-") ||
token.equals("*") || token.equals("/") );
}
/**
* Peforms integer evaluation on a single expression consisting of
* the specified operator and operands.
* #param operation operation to be performed
* #param op1 the first operand
* #param op2 the second operand
* #return value of the expression
*/
private int evaluateSingleOperator(char operation, int op1, int op2)
{
int result = 0;
switch (operation)
{
case ADD:
result = op1 + op2;
break;
case SUBTRACT:
result = op1 - op2;
break;
case MULTIPLY:
result = op1 * op2;
break;
case DIVIDE:
result = op1 / op2;
}
return result;
}
}
My ArrayStack class:
import java.util.Arrays;
public class ArrayStack<T> implements StackADT<T>
{
private final static int DEFAULT_CAPACITY = 100;
private int top;
private T[] stack;
/**
* Creates an empty stack using the default capacity.
*/
public ArrayStack()
{
this(DEFAULT_CAPACITY);
}
/**
* Creates an empty stack using the specified capacity.
* #param initialCapacity the initial size of the array
*/
public ArrayStack(int initialCapacity)
{
top = 0;
stack = (T[])(new Object[initialCapacity]);
}
/**
* Adds the specified element to the top of this stack, expanding
* the capacity of the array if necessary.
* #param element generic element to be pushed onto stack
*/
public void push(T element)
{
if (size() == stack.length)
expandCapacity();
stack[top] = element;
top++;
}
/**
* Creates a new array to store the contents of this stack with
* twice the capacity of the old one.
*/
private void expandCapacity()
{
stack = Arrays.copyOf(stack, stack.length * 2);
}
/**
* Removes the element at the top of this stack and returns a
* reference to it.
* #return element removed from top of stack
* #throws EmptyCollectionException if stack is empty
*/
public T pop() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("stack");
top--;
T result = stack[top];
stack[top] = null;
return result;
}
/**
* Returns a reference to the element at the top of this stack.
* The element is not removed from the stack.
* #return element on top of stack
* #throws EmptyCollectionException if stack is empty
*/
public T peek() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("stack");
return stack[top-1];
}
/**
* Returns true if this stack is empty and false otherwise.
* #return true if this stack is empty
*/
public boolean isEmpty()
{
// To be completed as a Programming Project
return top==0;
}
/**
* Returns the number of elements in this stack.
* #return the number of elements in the stack
*/
public int size()
{
// To be completed as a Programming Project
return top;
}
/**
* Returns a string representation of this stack.
* #return a string representation of the stack
*/
public String toString()
{
return stack.toString();
}
}
My input file of expressions (for testing purposes, the final two should throw the two exceptions):
8 4 + 3 *
7 5 2 * +
3 1 + 4 2 - *
5 8 2 - +
5 8 - +
6 3 2 -
My actual output:
8 4 + 3 *
The result is: 36
7 5 2 * +
3 1 + 4 2 - *
5 8 2 - +
5 8 - +
6 3 2 -
Obviously, I was expecting the first four expressions to follow as the first one did, and the final two to display my exception messages, but I can't seem to figure out where I've gone wrong.
You push the result to the evaluator stack.
You reuse the evaluator in the tester.
The evaluator is not clean when you start the second iteration in tester (the result of the previous expression is in the stack).
The easiest (and the correct) way to fix this is to change "return result;" to "return stack.pop();"
Next time use a debugger and step through your failing code. It's one of the most useful skills you can have in programming.
Asserting preconditions would help too. Check that stack is empty when you start evaluating an expression.
The exceptions are thrown but since class PostfixTester is using e.getMessgage(), you won't see the error in the output.
You should use, System.out.println(e.getMessage()) in order to print message. But even this change will print null.
You need to catch exceptions in PostfixEvaluator.evaluate() method and throw again with the message.

Decompress a string with more nested strings

The assignment consists in decompress a string. In particular, the code has to work for 3 samples as illustrated in the picture.
My code here works in the first 2 of the samples. However, I am not able to come up with the 3rd sample. Probably I did not understand probably the concept of recursion. Can you help me?
import java.util.Scanner;
public class Compression4 {
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
String input=in.next();
System.out.println(uncompress(input));
}
public static boolean flag = true;
public static String uncompress(String compressedText)
{
return uncompress(compressedText, "", "");
}
public static String getMultiple(String x, int N) {
if (N == 0) return "";
return ""+x+getMultiple(x,N-1);
}
public static String uncompress(String text, String count, String output)
{
if (text.equals(""))
{
return output;
}
if(text.charAt(0) == '(')
{
int FirstIndex = text.indexOf("(")+1;
String inner = text.substring(FirstIndex, text.lastIndexOf(")"));
//System.out.println(inner);
flag = false;
return uncompress (inner, count, output);
}
else if (Character.isLetter(text.charAt(0)))
{
//letter case - need to take the count we have accrued, parse it into an integer and add to output
if (flag==true)
{
//System.out.println(count);// * text.charAt(0);
String s = String.valueOf(text.charAt(0));
output += getMultiple(s,Integer.parseInt(count));
count ="1";
}
else
{
//System.out.println(count);// * text.charAt(0);
output += getMultiple(text,Integer.parseInt(count));
//System.out.println("output: "+output);
count="0";
}
}
else if(Character.isDigit(text.charAt(0)))
{
//digit case - need to add to the count but keep as a string because must be parsed later
if(flag)
count += (""+text.charAt(0));
else
{
count = "0";
count += (""+text.charAt(0));
}
}
//parse the *remainder* of the string, one character at a time, so pass in the substring(1)
return uncompress(text.substring(1), count, output);
}
}
Sorry for the long code but it's more easy to explain with code than with words.
Premise:
I think to the problem as an interpreter of a language to render a string
the language is simple and functional so recursive interpretation is possible
Algorithm phases:
First: tokenize the expression (to work at an higher level of abstraction)
Second: parse the expression just tokenized
Recursion: the logic is based on the syntax of the language. Key concepts of a recursion:
the base cases and the recursive cases
the state necessary to a single recursion (local variables of recursion, those passed as parameters to the recursive method)
the state for the all recursion (global variables of recursion, those read/write in some specific recursion)
I've made many comments to explain what the algorithm is doing. If it's not clear I can explain it better.
import java.util.ArrayList;
import java.util.List;
public class TestStringDecompression {
// simpleExpr examples: a | b | 123a | 123b | 123(a) | 123(ab) | 123(ba) | (ab) | (ba)
// 11ab = aaaaaaaaaaab = = expression = simpleExpr simpleExpr = 11a b
// 4(ab) = abababab = expression = simpleExpr = 4(ab)
// 2(3b3(ab)) = bbbabababbbbababab = expression = compositeExpr = 2 ( simpleExpr simpleExpr ) = 2 ( 3b 3(ab) )
public static void main(String[] args) {
System.out.println(new StringInflater().inflate("11ab"));
System.out.println(new StringInflater().inflate("4(ab)"));
System.out.println(new StringInflater().inflate("2(3b3(ab))"));
}
public static class StringInflater {
// This store the position of the last parsed token
private int posLastParsedToken = 0;
public String inflate(String expression) {
return parse(tokenize(expression), 0, false);
}
/**
* Language tokens:
* <ul>
* <li>literals:
* <ul>
* <li>intLiteral = [0-9]*</li>
* <li>charLiteral = [ab]</li>
* </ul>
* </li>
* <li>separators:
* <ul>
* <li>leftParen = '('</li>
* <li>rightParen = ')'</li>
* </ul>
* </li>
* </ul>
*/
private Object[] tokenize(String expression) {
List<Object> tokens = new ArrayList<Object>();
int i = 0;
while (i < expression.length()) {
if ('0' <= expression.charAt(i) && expression.charAt(i) <= '9') {
String number = "";
while ('0' <= expression.charAt(i) && expression.charAt(i) <= '9' && i < expression.length()) {
number += expression.charAt(i++);
}
tokens.add(Integer.valueOf(number));
} else {
tokens.add(expression.charAt(i++));
}
}
return tokens.toArray(new Object[tokens.size()]);
}
/**
* Language syntax:
* <ul>
* <li>simpleExpr = [intLiteral] charLiteral | [intLiteral] leftParen charLiteral+ rightParen</li>
* <li>compositeExpr = [intLiteral] leftParen (simpleExpr | compositeExpr)+ rightParen</li>
* <li>expression = (simpleExpr | compositeExpr)+</li>
* </ul>
*/
private String parse(Object[] tokens, int pos, boolean nested) {
posLastParsedToken = pos;
String result = "";
if (tokens[pos] instanceof Integer) {
/** it's a intLiteral */
// get quantifier value
int repetition = (int) tokens[pos];
// lookahead for (
if (tokens[pos + 1].equals("(")) {
// composite repetition, it could be:
// simpleExpr: "[intLiteral] leftParen charLiteral+ rightParen"
// compositeExpr: "[intLiteral] leftParen (simpleExpr | compositeExpr)+ rightParen"
result = parse(tokens, pos + 1, true);
} else {
// simple repetition, it could be:
// simpleExpr: [intLiteral] charLiteral
result = parse(tokens, pos + 1, false);
}
result = repeat(result, repetition);
// evaluate the rest of the expression because syntax allows it
if (posLastParsedToken + 1 == tokens.length) {
// end of the expression
return result;
} else {
// there are other simpleExpr or compositeExpr to parse
return result + parse(tokens, posLastParsedToken + 1, false);
}
} else if (tokens[pos].equals('(')) {
/** it's a leftParen */
// an open paren means what follow this token is considered nested (useful for string to treat as char sequence)
return parse(tokens, pos + 1, true);
} else if (tokens[pos].equals(')')) {
/** it's a rightParen */
// a closed paren, nothing to render
return "";
} else {
/** it's a charLiteral */
if (nested) {
// it's nested between paren, so more parsing is requested to consume next charLiteral or next simpleExpr or compositeExpr
return tokens[pos] + parse(tokens, pos + 1, nested);
} else {
// it's not nested between paren, return charLiteral as is
return "" + tokens[pos];
}
}
}
private String repeat(String s, int repetition) {
StringBuilder result = new StringBuilder();
for (int i = 0; i < repetition; i++) {
result.append(s);
}
return result.toString();
}
}
}

Why is my object staying null?

For some reason, I can't seem to fix this giving me a NullPointerException. I print out poly.term.degree without any errors, and then set poly.next equal to poly and then get a nullPointerException when I try to print out poly.next.term.degree which should seemingly be the same. I'm aware this is incomplete code but I think this is my main issue.
public Polynomial add(Polynomial p)
{
Polynomial newPoly = new Polynomial();
newPoly.poly = new Node(0,0,null);
Polynomial myCurr = this;
Polynomial otherCurr = p;
while(myCurr.poly != null)
{
int myDeg = myCurr.poly.term.degree;
int otherDeg = p.poly.term.degree;
float myCo = myCurr.poly.term.coeff;
float otherCo = otherCurr.poly.term.coeff;
if(myDeg == otherDeg)
{
System.out.println("degrees "+myDeg + " and "+ otherDeg+ " are equal, creating new node...");
Node n = new Node(myCo+otherCo,p.poly.term.degree, newPoly.poly.next);
System.out.println(newPoly.poly.term.degree);
newPoly.poly.next = newPoly.poly;
newPoly.poly = n;
System.out.println(newPoly.poly.next.term.degree); // Gives me a NullPointerException
}
Also, the constructors and everything for these classes is below.
package poly;
import java.io.*;
import java.util.StringTokenizer;
/**
* This class implements a term of a polynomial.
*
* #author runb-cs112
*
*/
class Term {
/**
* Coefficient of term.
*/
public float coeff;
/**
* Degree of term.
*/
public int degree;
/**
* Initializes an instance with given coefficient and degree.
*
* #param coeff Coefficient
* #param degree Degree
*/
public Term(float coeff, int degree) {
this.coeff = coeff;
this.degree = degree;
}
/* (non-Javadoc)
* #see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object other) {
return other != null &&
other instanceof Term &&
coeff == ((Term)other).coeff &&
degree == ((Term)other).degree;
}
/* (non-Javadoc)
* #see java.lang.Object#toString()
*/
public String toString() {
if (degree == 0) {
return coeff + "";
} else if (degree == 1) {
return coeff + "x";
} else {
return coeff + "x^" + degree;
}
}
}
/**
* This class implements a linked list node that contains a Term instance.
*
* #author runb-cs112
*
*/
class Node {
/**
* Term instance.
*/
Term term;
/**
* Next node in linked list.
*/
Node next;
/**
* Initializes this node with a term with given coefficient and degree,
* pointing to the given next node.
*
* #param coeff Coefficient of term
* #param degree Degree of term
* #param next Next node
*/
public Node(float coeff, int degree, Node next) {
term = new Term(coeff, degree);
this.next = next;
}
}
/**
* This class implements a polynomial.
*
* #author runb-cs112
*
*/
public class Polynomial {
/**
* Pointer to the front of the linked list that stores the polynomial.
*/
Node poly;
/**
* Initializes this polynomial to empty, i.e. there are no terms.
*
*/
public Polynomial() {
poly = null;
}
/**
* Reads a polynomial from an input stream (file or keyboard). The storage format
* of the polynomial is:
* <pre>
* <coeff> <degree>
* <coeff> <degree>
* ...
* <coeff> <degree>
* </pre>
* with the guarantee that degrees will be in descending order. For example:
* <pre>
* 4 5
* -2 3
* 2 1
* 3 0
* </pre>
* which represents the polynomial:
* <pre>
* 4*x^5 - 2*x^3 + 2*x + 3
* </pre>
*
* #param br BufferedReader from which a polynomial is to be read
* #throws IOException If there is any input error in reading the polynomial
*/
public Polynomial(BufferedReader br) throws IOException {
String line;
StringTokenizer tokenizer;
float coeff;
int degree;
poly = null;
while ((line = br.readLine()) != null) {
tokenizer = new StringTokenizer(line);
coeff = Float.parseFloat(tokenizer.nextToken());
degree = Integer.parseInt(tokenizer.nextToken());
poly = new Node(coeff, degree, poly);
}
}
I think the problem lies here:
newPoly.poly.next = newPoly.poly;
newPoly.poly = n;
At first you say, that newPoly.poly.next = newPoly.poly; so you assign the current element to the next, which is recursive. And then you say newPoly.poly = n; . So you assign a new element to newPoly. I think that the garbage collector deletes the newPoly element, because it is overwritten, so you lose the reference to the newPoly element. Which means when you access it later you get a nullpointer exception. You could fix this like this:
newPoly.poly.next = n;
//and dont forget to set the next pointer of the new elemnt to 0
n.next = NULL;
Just assign the new element to the next element.
EDIT
#hendersawn
You could sort the list. See below:
sort(Node head_p){ //do not change the head, or you will lose the beginning.
Node tmp_p;
Node curr_p = head_p;
while(curr_p != NULL){
if(curr_p.poly.term.degree < curr_p.next.poly.term.degree) //either degree is smaller or greater
{//swap
tmp_p = curr_p; //save first element
curr_p = curr_p.next; //set first element to second
//now the 2 element is the actual third element so we need
//to put the first between the second and the third
tmp_p.next = curr_p.next; //set next of first to third
curr_p.next = tmp_p; //set second element to the first that we saved before
}
curr_p = curr_p.next; //move to next element...rinse repeat
}
}
newPoly might be null
newPoly.poly might be null
newPoly.poly.next might be null
newPoly.poly.next.term might be null
or
newPoly.poly.next.term.degree might be null.
To avoid NullPointerException, you need to make sure that any member used is initialized with a proper value.
Nothing is obviously null that I can tell, however with four 'dots' (something.something.something.something) of Object Oriented Indirection, you're going to encounter this problem a lot. Usually two - three 'dots' on a single line are all you should ever do, but since that's more about the design and not the error, I digress.
The way to find this problem would be to either:
Put a breakpoint right at that line and see what the variables are there, and which one is null or
Do a System.out.println for each of the components to see which one breaks it, and work backwards from there. ex:
System.out.println(newPoly.poly.next.term.degree); // Gives me a NullPointerException
System.out.println(newPoly);
System.out.println(newPoly.poly);
System.out.println(newPoly.poly.next);
System.out.println(newPoly.poly.next.term);
because the nullPointerException would only get thrown on one of those (it can't be degree, otherwise that statement would have just printed 'null'
if I had to bet, I'd say it's probably newPoly.poly.next which is null
the lines:
newPoly.poly.next = newPoly.poly;
newPoly.poly = n;
Superficially seem like they would be the culprit of your trouble, since you're assigning the 'next' of your newPoly.poly, but then you re-assign your newPoly.poly, and lose that old reference to .next, I think.
Good luck! hope that helps.

Java program compiles fine, yet returning nullPointerException on run?

I've posted my program for review on code review (stackexchange).
Everything worked fine, After I came home I was told to use a IDE.
I opened my source with Eclipse IDE, and then I started getting (both on the IDE, or without) this error upon run:
Exception in thread "main" java.lang.NullPointerException
at games.Spin.rand(Spin.java:68)
at games.Spin.<init>(Spin.java:10)
at games.GameHandler.<init>(GameHandler.java:8)
at Mains.startGame(Mains.java:16)
at Mains.main(Mains.java:9)
Why is it doing that? My mate has reviewed my code, and could not find anything wrong with it?.
I am very new to java, tried at attempting going deeper in OO.
My code is located at code review thread (3 classes):
https://codereview.stackexchange.com/questions/28197/improving-my-java-object-oriented-review
What is wrong with it? Why is it giving me that exception?
Line 68: return r.nextInt(x);
public int rand(int x) {
return r.nextInt(x);
}
That's how I create r object:
/**
* Creating new Random object.
**/
private Random r = new Random();
Mains.java:
import games.GameHandler;
import java.util.Scanner;
import java.io.*;
public class Mains {
public static void main (String[] args) {
//Start the game
startGame();
}
private static void startGame() {
//Declares
GameHandler handler = new GameHandler();
Scanner console = new Scanner(System.in);
boolean game = true;
String input = "";
//Print program welcome text
handler.printStart();
//While in game...
while (game) {
//Getting input ready for new commands from the player
input = console.nextLine();
//Checking if input was set.
if (input != null) {
//Selecting the game you want to play.
handler.selectGame(input);
//If game was selected.. then.. let's start playing.
while (handler.inGame) {
//Use will say something.
input = console.nextLine();
//If it was "exit", it will go back and select another game.
if (input.equals("exit")) {
handler.exitGame();
} else {
//Play again.
handler.continueGame(input);
}
}
}
}
}
}
GameHandler.java:
package games;
import java.io.*;
public class GameHandler {
private String[] games = {"Spin", "Tof"};
private String[] navigation = {"Back", "Start"};
private Spin spin = new Spin();
private boolean spinGame = false;
private boolean tofGame = false;
public boolean inGame = false;
/**
* Method printStart
*
* Will welcome the player to the program.
*/
public void printStart() {
this.print(0, "Welcome to the program!");
this.print(0, "Please select a game: " + this.availableGames());
}
/**
* Method available games
*
* This will print all the games that are located in the games array in one row.
**/
private String availableGames() {
String names = "";
for (int i = 0; i < games.length; i++) {
names = (names + games[i]);
if (i < games.length -1) {
names = (names + ", ");
}
}
return names;
}
/**
* Method selectGame
*
* This will select the given game.
* #param command The entered command.
**/
public void selectGame(String command) {
if (this.inArray(command))
{
if (command.equalsIgnoreCase("spin")) {
this.startGame("spin");
} else if (command.equalsIgnoreCase("tof")) {
this.startGame("tof");
}
} else {
this.print(0, "Could not find game!");
}
}
/**
* Method inArray
*
* This will check if the entered game name is exisiting in the games array.
* If yes, will return a boolean true, else false.
*
* #param value The entered game name.
* #return boolean true/false.
**/
private boolean inArray(String value) {
int returning = 0;
for (String s : games) {
if (value.equalsIgnoreCase(s)) {
returning = 1;
}
}
if (returning == 1) {
return true;
} else {
return false;
}
}
/**
* Method startGame
*
* Will start the game, and print instructions.
* will set the game boolean to true.
**/
private void startGame(String game) {
switch (game) {
case "spin":
this.print(0, "Welcome to spin game!");
this.print(0, "Please click on any key to spin!");
spinGame = true;
break;
case "tof":
break;
}
inGame = true;
}
/**
* Method continueGame
*
* Will continue the game, either spin again, or print new question or even answer.
* #param command The entered command.
**/
public void continueGame(String command) {
while (inGame) {
if (spinGame) {
this.spinWheel();
// Break out of the loop.
break;
}
}
}
/**
* Method exitGame
*
* Exit the game..
**/
public void exitGame() {
spinGame = false;
tofGame = false;
this.printStart();
}
/**
* Method spinWheel
*
* This will spin the wheel.
**/
private void spinWheel() {
this.print(0, spin.spinWheel());
}
/**
* Method print
*
* Prints text using System.out
* #param type printing type (Println/print).
* #param message The message
**/
private void print(int type, String message) {
switch (type) {
case 0:
System.out.println(message);
break;
case 1:
System.out.print(message);
break;
}
}
}
Spin.java:
package games;
import java.util.Random;
public class Spin {
/**
* The base auth we are going to work with..
**/
private int auth = this.rand(1000) / 5;
/**
* Creating new Random object.
**/
private Random r = new Random();
/**
* Method spinWheel
*
* Spins the damn wheel..
* #return spinned value + if you won or not.
**/
public String spinWheel() {
return this.spinWheel(this.rand(100));
}
/**
* spinWheel
*
* Returning results.
**/
private String spinWheel(int number) {
int result = this.Calculate(this.rand(number));
if (result < 101) {
return "You have won the game!" + result;
} else {
return "You've lost the game!" + result;
}
}
/**
* Method calculate
*
* Calculates the spin.
* #return the spinned number.
**/
private int Calculate(int Number) {
int var = this.rand(101);
int holder = (var * Number) / 2;
return holder + this.auth;
}
/**
* Shortcut for nextInt of Random
**/
public int rand(int x) {
return r.nextInt(x);
}
}
rand is invoked before the Random instance r is initialised. Switch the order or these 2 statements
private int auth = this.rand(1000) / 5;
private Random r = new Random();
should be
private Random r = new Random();
private int auth = this.rand(1000) / 5;
Make the assignment of r the first thing in your Spinwheel class definition, i.e. put it before it is used in this.rand(1000):
public class Spin {
/**
* Creating new Random object.
**/
private Random r = new Random();
/**
* The base auth we are going to work with..
**/
private int auth = this.rand(1000) / 5;
r is null, so you can't call any instance method on r. Make sure you intialize r before using it.
More specifically, in this line:
private int auth = this.rand(1000) / 5;
you're calling the rand() method before r has been initialized (it's initialized right after).
This is the line causing the NullPointerException:
private int auth = this.rand(1000) / 5;
Since this line comes before the initialization for r, you are invoking rand before r was initialized. In that case r is null in rand and that's your exception.
This is obvious from your stack trace:
at games.Spin.rand(Spin.java:68)
at games.Spin.<init>(Spin.java:10)
Note that the exception is happening in the initializer. From there, it's easy to back out what is going on.
You need to initialize r first, that is, move the initialization line for r before the initialization line for auth. Thus:
private Random r = new Random();
private int auth = this.rand(1000) / 5;
This is because r is being used before it is instantiated within statement private int auth = this.rand(1000) / 5; . So , JVM is seeing r as null , which is leading to NPE. To get rid of this problem within Spin class declare the fields as follows:
private Random r = new Random();
private int auth = this.rand(1000) / 5;

RegEx -- Parsing strings in-between ${ }s but NOT '${ }'s

I want a regular expression that will extract _A_, 12345, Non_Literal_Left, and Non_Literal_Right from the following string:
... ${_A_}, ${12345}, '${Literal}' $yada yada'$[]' '${Non_Literal_Left} ${Non_Literal_Right}'
The closest I have been able to get is everything less the single quote restriction for literals:
Matcher matcher = Pattern.compile("\\$\\{(\\w+)\\}").matcher(s);
while (matcher.find()) {
result.add(matcher.group(1));
}
Which results in everything I want plus Literal, which I do not want to match.
Thanks in advance...
You could simply use a negative lookbehind:
"(?<!')\\$\\{(\\w+)\\}"
This will now only match if the $ is not preceded by '.
As Matt Ball mentioned in a comment, it might make sense to add another negative lookahead to the end, too:
"(?<!')\\$\\{(\\w+)\\}(?!')"
However, this will only matter if you have invalid/unmatched usage of ' as in ${Literal}' (in this case my first regex will still match Literal, the latter won't).
That was a joy.
Something tells me a RegEx expression would have been a little cleaner.
/**
* Utility class for parsing record field parameters in properties.
*
* #author Ryan
*
*/
public static class PropertyParser {
/**
* Stores the results of parsing a property.
*
* #author Ryan
*
*/
public static class ParsedParameters {
private final Set<String> literals;
private final Set<String> parameters;
private ParsedParameters() {
this.parameters = new HashSet<String>();
this.literals = new HashSet<String>();
}
/**
* Adds a literal property value to this object.
*
* #param string The literal property value to add to this object.
*/
private void addLiteral(String string) {
this.literals.add(string);
}
/**
* Adds a parameter name to this object.
*
* #param string The parameter name to add to this object.
*/
private void addParameter(String string) {
this.parameters.add(string);
}
/**
* Returns the set of literals stored in this object.
*
* #return The set of literals stored in this object.
*/
public Set<String> getLiterals() {
return this.literals;
}
/**
* Returns the set of parameters stored in this object.
*
* #return The set of parameters stored in this object.
*/
public Set<String> getParameters() {
return this.parameters;
}
}
private static final String BAD_FIELD_CHAR =
"Illegal character detected for field parameter: %c";
/**
* Extracts placeholder field name parameters from the input string.
* <p>
* Single quotes can be used to avoid the parser interpreting the ${...}
* as a field parameter.
* <p>
* For example, the parser would not detect any field parameters in the following string:
* <p>
* #!/bin/bash<br>
* # Echos the first argument<br>
* echo '${1}'<br>
* <p>
* The {#link #PropertySubstitutor()} is responsible for removing the single quotes
* surrounding the parameter when substituting the actual property value(s).
* <p>
* <b>Nested Parameters</b>
* <p>
* This parser itself will only parse the inner-most parameter or literal.
* <p>
* For example, ${Some${Value}} would actually be treated as a legal string, with
* 'Value' as the only field parameter extracted. During runtime substitution,
* this would result in ${Somebody} if the record value for the field "Value" was "body".
* <p>
* Theoretically, this parser could then be ran again to extract this generated parameter.
*
* #param string The property to parse for field parameters.
* #return An object containing the parsed parameters and literal values.
* #throws IllegalArgumentException If the property contains parameter syntax
* (i.e. ${text}) but contains illegal characters for the field.
* <p>
* Allowed characters for field names are alpha-numeric and underscores.
*/
public static ParsedParameters parseParametersAndLiterals(String string)
throws IllegalArgumentException {
if ((string == null) || string.isEmpty()) {
return new ParsedParameters();
}
ParsedParameters result = new ParsedParameters();
StringBuffer param = null;
Character badChar = null;
char c;
char p = '^';
boolean close = false;
boolean lQuote = false;
boolean open = false;
int l = string.length();
for (int i = 0; i < l; ++i) {
c = string.charAt(i);
if (!lQuote && (p == '\'') && (c == '$')) {
lQuote = true;
} else if ((p == '$') && (c == '{')) {
param = new StringBuffer();
open = true;
badChar = null;
} else if (open
&& (((c == '}') && (!lQuote || ((1 + i) == l))) || (lQuote && (p == '}')))) {
open = false;
close = true;
} else if (open) {
boolean validCharacter = Character.isLetterOrDigit(c) || (c == '_');
if (validCharacter || (lQuote && (c != '}'))) {
param.append(c);
}
if (!validCharacter && (c != '}')) {
badChar = c;
}
}
if (close) {
if ((badChar != null) && !(lQuote && (p == '}') && (c == '\''))) {
throw new IllegalArgumentException(String.format(BAD_FIELD_CHAR, badChar));
} else if (c != '\'') {
if (param.length() > 0) {
result.addParameter(param.toString());
}
} else {
result.addLiteral(param.toString());
}
lQuote = false;
close = false;
badChar = null;
}
p = c;
}
return result;
}
}
And tests, of course.
public class TestPropertyParser {
private Set<String> literals;
private Set<String> params;
private void assertLiteralsContains(String string) {
assertTrue(this.literals.contains(string));
}
private void assertParamsContains(String string) {
assertTrue(this.params.contains(string));
}
private void assertResultSizes(Integer paramSize, Integer literalSize) {
if (paramSize != null) {
assertNotNull(this.params);
assertEquals((int) paramSize, this.params.size());
} else {
assertNull(this.params);
}
if (literalSize != null) {
assertNotNull(this.literals);
assertEquals((int) literalSize, this.literals.size());
} else {
assertNull(this.literals);
}
}
private void parseAndSet(String stringToParse) {
ParsedParameters result = PropertyParser.parseParametersAndLiterals(stringToParse);
this.literals = result.getLiterals();
this.params = result.getParameters();
}
#Before
public void setup() {
this.params = new HashSet<String>();
this.literals = new HashSet<String>();
}
#Test(expected = IllegalArgumentException.class)
public void testParserInvalidParameterQuoteLeft() {
parseAndSet("'${Invalid Parameter}");
}
#Test(expected = IllegalArgumentException.class)
public void testParserInvalidParameterQuoteRight() {
parseAndSet("${Invalid Parameter}'");
}
#Test(expected = IllegalArgumentException.class)
public void testParserInvalidParameterSpaces() {
parseAndSet(" ${Invalid Parameter}");
}
#Test
public void testParserValidStrings() {
// Initialization condition.
assertResultSizes(0, 0);
// Null string.
parseAndSet(null);
assertResultSizes(0, 0);
// Empty string.
parseAndSet(new String());
assertResultSizes(0, 0);
// Single parameter.
parseAndSet("... ${_A_}, $yada yada'$[]' '${");
assertResultSizes(1, 0);
assertParamsContains("_A_");
// Many parameters and one literal.
parseAndSet("... ${_A_}, ${12345}, '${Literal}''${Non_Literal_Left} ${Non_Literal_Right}' ");
assertResultSizes(4, 1);
assertParamsContains("_A_");
assertParamsContains("12345");
assertParamsContains("Non_Literal_Left");
assertParamsContains("Non_Literal_Right");
assertLiteralsContains("Literal");
// Nested literal and odd bracket placements.
parseAndSet("''${Totally}''$}{$'${Single}");
assertResultSizes(1, 1);
assertParamsContains("Single");
assertLiteralsContains("Totally");
// Subset of ASCII characters.
parseAndSet("`1234567890-=qwertyuiop[]\\asdfghjkl;'zxcvbnm,./!##$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:\"ZXCVBNM<>?");
assertResultSizes(0, 0);
// Illegal characters in literal.
parseAndSet("'${This literal is completely valid}'");
assertResultSizes(0, 1);
assertLiteralsContains("This literal is completely valid");
// Test incomplete literal, no closure.
parseAndSet("'${This literal is never closed");
assertResultSizes(0, 0);
// Test incomplete parameter from left.
parseAndSet("${Never_Closed");
assertResultSizes(0, 0);
// And again... with a parameter at the end.
parseAndSet("${Never_Closed${But_This_Is}");
assertResultSizes(1, 0);
assertParamsContains("But_This_Is");
// Empty parameter.
parseAndSet("${}");
assertResultSizes(0, 0);
// Restarting a new parameter within an already open parameter.
parseAndSet("${Perfectly valid${a}");
assertResultSizes(1, 0);
assertParamsContains("a");
// Variation of the above with quotes.
parseAndSet("'${Perfectly valid'${a}");
assertResultSizes(1, 0);
assertParamsContains("a");
// Variation of the above with quotes.
parseAndSet("${Perfectly valid'${a}");
assertResultSizes(1, 0);
assertParamsContains("a");
// Variation of the above with quotes.
parseAndSet("${Perfectly valid${a}'");
assertResultSizes(1, 0);
assertParamsContains("a");
// Variation of the above with quotes.
parseAndSet("${Perfectly valid'${a}'");
assertResultSizes(0, 1);
assertLiteralsContains("a");
// Variation of the above with spaces.
parseAndSet(" ${ Perfectly valid${a} ");
assertResultSizes(1, 0);
assertParamsContains("a");
// TODO Determine what the desired behavior is for nested literals and parameters.
// Test nested parameter in literal.
parseAndSet("'${Nested ${Parameter}}'");
assertResultSizes(1, 0);
assertParamsContains("Parameter");
// Nested parameter.
parseAndSet("${Nested_${Parameter}}'");
assertResultSizes(1, 0);
assertParamsContains("Parameter");
// Literal nested in a parameter.
parseAndSet(" ${Nested'${Literal}'}");
assertResultSizes(0, 1);
assertLiteralsContains("Literal");
}
}

Categories

Resources