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

时间:2015-11-15 05:47:07

标签: java html compiler-construction syntax-error

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

我无法弄清楚为什么我会在以下代码中出现错误。错误是在paragraph()方法中抛出。我收到以下错误:“线程中的异常”主“Exceptions.CompilerException:语法错误:段落+”因此,当我的语法分析器命中第一个列表项时,错误正在段落方法中抛出。

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

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

text是一个.z和特殊字符,包括':'

这是文本文件:

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

这是java类:

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)

1 个答案:

答案 0 :(得分:1)

<script> var isFirst = true; function toggle_visibility(id) { if(!isActivated(id)) { toggle(id); if(isFirst != true) { if(id == "t1") { toggle("t2"); } else if(id == "t2") { toggle("t1"); } } } isFirst = false; } function toggle(id) { var text = document.getElementById(id); if(text.getAttribute("data-toggled") == "1") { text.setAttribute("data-toggled", "0"); text.innerHTML = text.getAttribute("data-original"); } else { text.innerHTML = text.getAttribute("data-after"); text.setAttribute("data-toggled", "1"); } } function isActivated(id) { var element = document.getElementById(id); if(element.getAttribute('data-toggled') == "1") { return true; } else { return false; } } </script> 的处理不正确。如果您识别出“+”,则会调用innerItem,它会消耗所有令牌,包括“;”。返回后,listitem返回innerItem,无法查找另一个内部项目并最终抛出错误。

paragraph

中删除此行
innerItem

这是 else {innerItem();} 的修复:

@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;
}

关于while中的条件:

paragraph

现在我根本不确定这一点。通常,我希望列表(+ ...;)由一系列相同的内部标记组成,这意味着您需要将循环移动到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)