我正在为Infix表示法编写一个Parser。 在if语句中,我声明变量newchild。否则我希望它抛出异常。但是当我超出范围时,编译器不再知道变量。 我无法在if语句之前声明它,因为根据我们所处的情况,变量被赋予不同的数据类型。
我该怎么做才能解决这个问题?
public class ParserForInfixNotation {
public Node parse(List<String> tokenList) {
Stack<String> myStack = new Stack<String>();
int i =1;
while(i <= tokenList.size()){ //wir gehen alle Eintraege in der Liste durch
if(Character.isDigit(tokenList.get(i).charAt(1))){
int value = Integer.parseInt(tokenList.get(i)); //falls der Eintrag eine Zahl ist, wird ein neuer Leaf erstellt
Leaf res = new Leaf(value);
}
else if(tokenList.get(i) == "("){ // falls der Eintrag eine Klammer ist, wird geschaut, ob in der Klammer ein Unary oder Binary OpNode definiert ist
if (tokenList.get(i+1) == "-") {
// Fall Unary
int j = i+1;
//am Liebsten ein rekursiver Aufruf auf parser mit nem TeilString des Oberen Strings, der genau den naechsten Node beschreibt
int anzahlklammern = 0;
boolean end = false;
if((Character.isDigit(tokenList.get(j).charAt(1))) || (tokenList.get(j+1) == ")")){
Leaf newchild = new Leaf(Integer.parseInt(tokenList.get(j)));
}
else if(tokenList.get(j) == "("){
while(!end){
if(tokenList.get(j) == ")" && anzahlklammern == 1){
end = true;
}
else if(tokenList.get(j) == ")" && j > i+3){ //die Klammer muss mindestens 2 Stellen enthalten
anzahlklammern--;
j++;
}
else if(tokenList.get(j) == "("){
anzahlklammern++;
j++;
}
else if ((Character.isDigit(tokenList.get(j).charAt(1))) || tokenList.get(j) == "+" || tokenList.get(j) == "*" || tokenList.get(j) == "-"){
j++;
}
else{
throw new IllegalArgumentException();
}
}
List<String> neu = new ArrayList<>();
for (int l = i+2; l<j;l++){
neu.add(tokenList.get(l));
}
Node newchild = parse(neu);
}
else {
throw new IllegalArgumentException();
}
UnaryOpNode res = new UnaryOpNode('-',newchild);
}
else if((tokenList.get(i+1) == "(") || (Character.isDigit(tokenList.get(i+1).charAt(1)))){ //Fall Binary
if (Character.isDigit(tokenList.get(i+1).charAt(1)) && (tokenList.get(i+2) == "+" || tokenList.get(i+2) == "*")){
Leaf newchildleft = new Leaf(Integer.parseInt(tokenList.get(i+1)));
if(tokenList.get(i+2) == "+"){
Character operator = '+';
}
else if(tokenList.get(i+2) == "*"){
Character operator = '*';
}
int j = i+3;
if(Character.isDigit(tokenList.get(j).charAt(1))){
Leaf newchildright = new Leaf(Integer.parseInt(tokenList.get(j)));
}
else if(tokenList.get(j) == "("){
boolean end = false;
int anzahlklammern =0 ;
while(!end){
if(tokenList.get(j) == ")" && anzahlklammern == 1){
end = true;
}
else if(tokenList.get(j) == ")" && j > i+5){ //die Klammer muss mindestens 2 Stellen enthalten
anzahlklammern--;
j++;
}
else if(tokenList.get(j) == "("){
anzahlklammern++;
j++;
}
else if ((Character.isDigit(tokenList.get(j).charAt(1))) || tokenList.get(j) == "+" || tokenList.get(j) == "*" || tokenList.get(j) == "-"){
j++;
}
else{
throw new IllegalArgumentException();
}
}
List<String> neu = new ArrayList<>();
for (int l = i+4; l<j;l++){
neu.add(tokenList.get(l));
}
Node newrightchild = parse(neu);
}
else{
throw new IllegalArgumentException();
}
}
else if(tokenList.get(i+1) == "("){
int j= i+1;
boolean end = false;
int anzahlklammern =0 ;
while(!end){
if(tokenList.get(j) == ")" && anzahlklammern == 1){
end = true;
}
else if(tokenList.get(j) == ")" && j > i+3){ //die Klammer muss mindestens 2 Stellen enthalten
anzahlklammern--;
j++;
}
else if(tokenList.get(j) == "("){
anzahlklammern++;
j++;
}
else if ((Character.isDigit(tokenList.get(j).charAt(1))) || tokenList.get(j) == "+" || tokenList.get(j) == "*" || tokenList.get(j) == "-"){
j++;
}
else{
throw new IllegalArgumentException();
}
}
List<String> neu = new ArrayList<>();
for (int l = i+2; l<j;l++){
neu.add(tokenList.get(l));
}
Node newleftchild = parse(neu);
if(tokenList.get(j+1) == "+"){
Character operator = '+';
}
else if(tokenList.get(j+1) == "*"){
Character operator = '*';
}
else{
throw new IllegalArgumentException();
}
if(tokenList.get(j+2)== "("){
int k= j+3;
end = false;
anzahlklammern =0 ;
while(!end){
if(tokenList.get(k) == ")" && anzahlklammern == 1){
end = true;
}
else if(tokenList.get(k) == ")" && k > j+5){ //die Klammer muss mindestens 2 Stellen enthalten
anzahlklammern--;
k++;
}
else if(tokenList.get(k) == "("){
anzahlklammern++;
k++;
}
else if ((Character.isDigit(tokenList.get(k).charAt(1))) || tokenList.get(k) == "+" || tokenList.get(k) == "*" || tokenList.get(k) == "-"){
k++;
}
else{
throw new IllegalArgumentException();
}
}
List<String> neu2 = new ArrayList<>();
for (int l = j+4; l<k;l++){
neu.add(tokenList.get(l));
}
Node newrightchild = parse(neu2);
}
else if(Character.isDigit(tokenList.get(j+2).charAt(1))){
Leaf newrightchild = new Leaf(Integer.parseInt(tokenList.get(j+2)));
}
else{
throw new IllegalArgumentException();
}
}
BinaryOpNode res = new BinaryOpNode(operator, newleftchild, newrightchild);
}
else{
throw new IllegalArgumentException();
}
}
else{
throw new IllegalArgumentException();
}
}
return res;
}
答案 0 :(得分:1)
这是关于范围。变量的范围是声明的块,并在其中阻塞。块是否是if
语句的块,某些其他语句,或者只是为了定义范围而放在那里的块都没有关系。
您遇到了这个问题:
{
Leaf leaf = new Leaf();
}
doSomethingWith(leaf); // compiler error - there is no `leaf` in this scope.
你可以用以下方法修复它:
Leaf leaf;
{
leaf = new Leaf();
}
doSomethingWith(leaf);
如果leaf
的分配有可能发生 - 例如,如果它在if
块中,那么您将获得编译错误说variable leaf may not have been initialized
。您可以通过首先初始化为某些回退值来解决此问题。它经常是空的:
Leaf leaf = null;
if(...) {
leaf = new Leaf();
}
doSomethingWith(leaf);
但是现在你的代码必须应对leaf == null
的可能性 - 这导致代码过于复杂或脆弱。找到避免分配null的方法,或者如果你不能保持易受攻击的代码块被隔离,那么该范围之外的任何东西都不需要处理null变量的可能性。
答案 1 :(得分:0)
你可以这样做:
int value = = -1;
Leaf res = null;
if(Character.isDigit(tokenList.get(i).charAt(1))){
value =Integer.parseInt(tokenList.get(i));
res = new Leaf(value);
}
并查看 if 哪些值存储在变量 值 和 < EM> RES 强>
答案 2 :(得分:0)
一种方法是移动/复制这一行:
UnaryOpNode res = new UnaryOpNode('-',newchild);
因此它包含在If和else中,如果是这样的话:
if((Character.isDigit(tokenList.get(j).charAt(1))) || (tokenList.get(j+1) == ")"))
{
Leaf newchild = new
Leaf(Integer.parseInt(tokenList.get(j)));
UnaryOpNode res = new UnaryOpNode('-',newchild);
}
else if(tokenList.get(j) == "("){
while(!end){
if(tokenList.get(j) == ")" && anzahlklammern == 1){
end = true;
}
else if(tokenList.get(j) == ")" && j > i+3){
anzahlklammern--;
j++;
}
else if(tokenList.get(j) == "("){
anzahlklammern++;
j++;
}
else if ((Character.isDigit(tokenList.get(j).charAt(1))) || tokenList.get(j) == "+" || tokenList.get(j) == "*" || tokenList.get(j) == "-"){
j++;
}
else{
throw new IllegalArgumentException();
}
}
List<String> neu = new ArrayList<>();
for (int l = i+2; l<j;l++){
neu.add(tokenList.get(l));
}
Node newchild = parse(neu);
UnaryOpNode res = new UnaryOpNode('-',newchild);
}
else {
throw new IllegalArgumentException();
}