我可以在“+”上使用 .equals() 吗?不确定为什么会在此处抛出错误

Can I use .equals() on '+'? Not sure why error is being thrown here

这是 HTML 降价语言的语法分析器。

我无法弄清楚为什么我会在以下代码中抛出错误。错误是在 paragraph() 方法中抛出的。我收到以下错误:"Exception in thread "main" Exceptions.CompilerException: Syntax Error: paragraph + " 因此,当我的语法分析器命中第一个列表项时,错误被抛出到 paragraph 方法中。

基本上,我有一个队列 (inputQueue),其中填充了以下文本文件 (#BEGIN, ^, <, The, Simpsons... ) 中的每个字符串,它应该 运行 可以通过以下 class。字符串 Tokens.sLIST 声明为“+”。

'#BEGIN = sHTML'
'^ = sHEAD'
'< = sTITLE'
'> = eTITLE'
'{ = sPARAGRAPH'
'+ = sLIST'
'; = eLIST'

文本是 a..z 和包括 ':' 在内的特殊字符

这是文本文件:

#BEGIN 
^ < The Simpsons > ^ 
{ 
  The members of the The Simpsons are: 
     + Homer Simpson ; 
     + Marge Simpson ; 
     + Bart Simpson ; 
     + Lisa Simpson ; 
     + Maggie Simpson ; 
} 
#END 

这里是 java class:

package edu.towson.cis.cosc455.ctrader.project1.implementation;

import java.util.Arrays;

import Exceptions.CompilerException;

public class SyntaxAnalyzer implements     edu.towson.cis.cosc455.ctrader.project1.interfaces.SyntaxAnalyzer {

@Override
public void markdown() throws CompilerException {
    if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.sHTML)){
            Compiler.outputQueue.add(Compiler.inputQueue.remove());
            head();
            body();
            //System.out.print(Compiler.inputQueue.peek());
            if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.eHTML)){
                System.out.println("Syntax Check complete");
            }else throw new CompilerException("Syntax Error: .mkd file does not end with #END");
    }else throw new CompilerException("Syntax Error: .mkd file does not start with #BEGIN");
    return;
}

@Override
public void head() throws CompilerException {
    if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.sHEAD)){
        Compiler.outputQueue.add(Compiler.inputQueue.remove());
        title();
        if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.eHEAD)){
            Compiler.outputQueue.add(Compiler.inputQueue.remove());
        }
        else throw new CompilerException("Syntax Error: head");
    }
    else return;
}

@Override
public void title() throws CompilerException {
    if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.sTITLE)){
        Compiler.outputQueue.add(Compiler.inputQueue.remove());
        innerText();
        if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.eTITLE)){
            Compiler.outputQueue.add(Compiler.inputQueue.remove());
        }
        else throw new CompilerException("Syntax Error: title");
    }
    else return;
}



@Override
public void body() throws CompilerException {
        paragraph(); 
        innerItem();
        checkSyntax();
}


@Override
public void paragraph() throws CompilerException {

    if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.sPARAGRAPH)){
        Compiler.outputQueue.add(Compiler.inputQueue.remove());
        innerItem();
        if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.ePARAGRAPH)){
            Compiler.outputQueue.add(Compiler.inputQueue.remove());
        }
        else throw new CompilerException("Syntax Error: paragraph " + Compiler.inputQueue.peek());
    }
    else return;

}

@Override
public void innerText() throws CompilerException {
        while(!Arrays.asList(Tokens.TOKENS).contains(Compiler.inputQueue.peek().toUpperCase()))
            Compiler.outputQueue.add(Compiler.inputQueue.remove());
}

@Override
public void variableDefine() throws CompilerException {
    // TODO Auto-generated method stub

}

@Override
public void variableUse() throws CompilerException {
    // TODO Auto-generated method stub

}

@Override
public void bold() throws CompilerException {
    if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.sBOLD)){
        Compiler.outputQueue.add(Compiler.inputQueue.remove());
        innerText();
        if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.eBOLD)){
            Compiler.outputQueue.add(Compiler.inputQueue.remove());
        }
        else throw new CompilerException("Syntax Error: bold");
    }
    else return;

}

@Override
public void italics() throws CompilerException {
    if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.sITALIC)){
        Compiler.outputQueue.add(Compiler.inputQueue.remove());
        innerText();
        if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.eITALIC)){
            Compiler.outputQueue.add(Compiler.inputQueue.remove());
        }
        else throw new CompilerException("Syntax Error: italic");
    }
    else return;

}

@Override
public void listitem() throws CompilerException {
    if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.sLIST)){
        Compiler.outputQueue.add(Compiler.inputQueue.remove());
        innerText();
        if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.eLIST)){
            Compiler.outputQueue.add(Compiler.inputQueue.remove());
        }
        else throw new CompilerException("Syntax Error: list item");
    }
    else return;

}

@Override
public void innerItem() throws CompilerException {
    if(Compiler.inputQueue.peek().equals(Tokens.sAUDIO))
        audio();
    else if(Compiler.inputQueue.peek().equals(Tokens.sBOLD))
        bold();
    else if(Compiler.inputQueue.peek().equals(Tokens.sITALIC))
        italics();
    else if(Compiler.inputQueue.peek().equals(Tokens.sLINKDESCRIPTION))
        link();
    else if(Compiler.inputQueue.peek().equals(Tokens.sLIST))
        {System.out.println("here");listitem();}
    else if(Compiler.inputQueue.peek().equals(Tokens.sAUDIO))
        audio();
    else if(!Arrays.asList(Tokens.TOKENS).contains(Compiler.inputQueue.peek().toUpperCase()))
        innerText();        
    else {innerItem();}


}


@Override
public void link() throws CompilerException {
    if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.sLINKDESCRIPTION)){
        Compiler.outputQueue.add(Compiler.inputQueue.remove());
    innerText();
    if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.eLINKDESCRIPTION))
        Compiler.outputQueue.add(Compiler.inputQueue.remove());
    else throw new CompilerException("Syntax Error: list item");

    if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.sADDRESS))
        Compiler.outputQueue.add(Compiler.inputQueue.remove());
    innerText();
    if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.eADDRESS))
        Compiler.outputQueue.add(Compiler.inputQueue.remove());
    else throw new CompilerException("Syntax Error: list item");
    }
  else return;

}

@Override
public void audio() throws CompilerException {
    if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.sAUDIO)){
        Compiler.outputQueue.add(Compiler.inputQueue.remove());
        innerText();
        if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.sADDRESS)){
            Compiler.outputQueue.add(Compiler.inputQueue.remove());
            innerText();
        if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.eADDRESS))
            Compiler.outputQueue.add(Compiler.inputQueue.remove());
        }else throw new CompilerException("error: address");
    }
}

@Override
public void video() throws CompilerException {
    // TODO Auto-generated method stub

}

@Override
public void newline() throws CompilerException {
    // TODO Auto-generated method stub

}

public void checkSyntax() throws CompilerException {
    if(!Arrays.asList(Tokens.TOKENS).contains(Compiler.inputQueue.peek().toUpperCase()) || !Compiler.inputQueue.peek().equals(Tokens.eHTML))
        throw new CompilerException("Syntax Error - Unexpected token: " + Compiler.inputQueue.peek());
}

}

这是堆栈:

Exception in thread "main" Exceptions.CompilerException: Syntax Error: paragraph +
at edu.towson.cis.cosc455.ctrader.project1.implementation.SyntaxAnalyzer.paragraph(SyntaxAnalyzer.java:68)
at edu.towson.cis.cosc455.ctrader.project1.implementation.SyntaxAnalyzer.body(SyntaxAnalyzer.java:53)
at edu.towson.cis.cosc455.ctrader.project1.implementation.SyntaxAnalyzer.markdown(SyntaxAnalyzer.java:14)
at edu.towson.cis.cosc455.ctrader.project1.implementation.Compiler.main(Compiler.java:57)

innerItem 的处理不正确。如果识别出“+”,则调用 listitem,它会消耗直到并包括“;”的所有标记。在您 return、innerItem return 进入 paragraph 后,它无法寻找另一个内部项目并最终抛出错误。

innerItem 中删除这一行:

 else {innerItem();}

这是 paragraph 的修复:

@Override
public void paragraph() throws CompilerException {
    if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.sPARAGRAPH)){
        Compiler.outputQueue.add(Compiler.inputQueue.remove());
        while( onceMore() ){
            innerItem();
        }
        if(Compiler.inputQueue.peek().equalsIgnoreCase(Tokens.ePARAGRAPH)){
            Compiler.outputQueue.add(Compiler.inputQueue.remove());
        }
        else throw new CompilerException("Syntax Error: paragraph " + Compiler.inputQueue.peek());
    }
    else return;
}

暂时的情况:

boolean onceMore(){
    String next = Compiler.inputQueue.peek();
    return next.equalsIgnoreCase(Tokens.sAUDIO) ||
           next.equalsIgnoreCase(Tokens.sBOLD) ||
           ...;
}

现在我对此完全不确定。通常,我希望列表 (+...;) 由一系列相同的内部标记组成,这意味着您需要将循环移动到 innerItem,其中 Tokens.sList 被识别:

...
else if(Compiler.inputQueue.peek().equals(Tokens.sLIST)){
    do { listitem();
    } while( Compiler.inputQueue.peek().equals(Tokens.sLIST) );
} ...

和其他标记(粗体、斜体,可能出现在任何文本中,甚至在“+”和“;”之间。但我不知道您要实现的语法,所以我可能是错的。

最后评论:您和您的代码将从一些辅助方法中受益匪浅,以缩写令人难以置信的表达式,例如 void gobble()boolean test(String token)void passthru()