Итак, я пытаюсь реализовать шунтирующий двор для работы с Logic, я думал, что это будет легко, пока я не столкнулся с проблемой установки приоритета для материала условного (->) и bi-conditional (< ->), поскольку они должны быть представлены как String, а не char. Мне нужно иметь возможность читать файл с таким заявлением, как (A|B) -> !C
(что означает: (A ИЛИ B) подразумевает NOT C) и переводит его в постфиксную нотацию. Я продолжаю получать исключение NullPointerException в строке 115, и я действительно не уверен, почему, могу ли я установить только случай, используя значения char? Или мне нужно найти другой метод установки приоритета для символов. Вот мой кодImplemeting Shunting yard с логикой
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
import java.util.Scanner;
import java.io.File;
import java.util.ArrayList;
import java.io.Reader;
public class ShuntingYard
{
public static ArrayList<String> symbols = new ArrayList<String>();
public static ArrayList<String> letters = new ArrayList<String>();
public static String path = "";
public static void main(String args[])
{
ShuntingYard sy = new ShuntingYard();
//Scans in File.
Scanner scan = new Scanner(System.in);
String prompt = "Please specify the file path.\n Use the form: D:\\DiscreteMath\\inputFile.txt";
System.out.println(prompt);
path = scan.next();
File file = new File(path);
String infix = "";
try{
scan = new Scanner(file);
infix = scan.nextLine();
}
catch(IOException e)
{
System.err.println(" No file");
}
// calls postfix function
String postfix = sy.postfix(infix);
System.out.println("\nPostfix expression : " + postfix);
String al = "A,B,C,D,E,";
}
public enum Precedence
{
//configure precedence of symbols and operands.
lparen(0), rparen(1), not(2), and(3), or(4), mc(5), bc(6), eos(7), operand(8);
private int index;
Precedence(int index)
{
this.index = index;
}
public int getIndex()
{
return index;
}
}
private static final int[] isp = {0,19,12,12,13,13,0};
private static final int[] icp = {20,19,12,12,13,13,0};
private static final String[] operators = {"{","}","!","&","|","->","<->"," "};
//initializes stack
private Precedence[] stack;
private int top;
private Precedence pop()
{
return stack[top--];
}
private void push(Precedence ele)
{
stack[++top] = ele;
}
//Sets Precedence of symbols.
public Precedence getToken(String symbol)
{
switch(symbol)
{
case "(" : return Precedence.lparen;
case ")" : return Precedence.rparen;
case "!" : return Precedence.not;
case "&" : return Precedence.and;
case "|" : return Precedence.or;
case "->" : return Precedence.mc;
case "<->" : return Precedence.bc;
case " " : return Precedence.eos;
default : return Precedence.operand;
}
}
//Changes infix to postfix notation then returns a string value.
public String postfix(String infix)
{
String postfix = "";
top = 0;
stack = new Precedence[infix.length()];
Precedence token;
for(int i = 0; i<infix.length(); i++)
{
token = getToken(Character.toString(infix.charAt(i)));
if(token == Precedence.operand)
{
postfix = postfix + infix.charAt(i);
}
else if(token == Precedence.rparen)
{
while(stack[top] != Precedence.lparen)
{
postfix = postfix + operators[pop().getIndex()];
}
pop();
}
else
{
while(isp[stack[top].getIndex()] >= icp[token.getIndex()])
{
postfix = postfix + operators[pop().getIndex()];
}
push(token);
}
}
while((token = pop()) != Precedence.eos)
{
postfix = postfix + operators[token.getIndex()];
}
return postfix;
}
}
Запуск через отладчик ошибки легко отслеживать. В первом прогоне через постфиксный метод он считывает первый токен, который является Precedence.lparen, а не операндом или rparen, следовательно, он переходит в блок else. В этот момент стек пуст, заполненный нулем, дающий исключение нулевого указателя. –