Cocol / R预测解析器实现Java

时间:2014-09-05 03:56:41

标签: java parsing

我正在研究COCOL / R的预测解析器

这是我现在试图解析的语法部分:

enter image description here

平方括号表示1或无 花括号意味着0或更多。

public void Cocol( ){
    lookahead = in.next();
    if(lookahead.equals("COMPILER")){
        match("COMPILER");
        match("ident");
        ScannerSpecification();
        match("END");
        match("ident");
        match(".");
    }
    else{
        System.out.println("SYNTAX ERROR: \nCOMPILER expected, Found: "+lookahead);
        try {
            ArrayList<Integer> line = findLineOf(lookahead);
            System.out.println("Line: "+line);
        } catch (Exception ex) {
            Logger.getLogger(ScannerCocol.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}

public void ScannerSpecification(){
    // 1 o mas veces “CHARACTERS” { SetDecl }
    if(lookahead.equals("CHARACTERS")){
        match("CHARACTERS");
        // 0 or More SETDecl

    }
    if (lookahead.equals("KEYWORDS")){
        //PENDING....     
    }

    if( WhiteSpaceDecl()){
          //PENDING....
    }
    boolean res=match(".");
    if(res==false){
        System.out.println("SYNTAX ERROR: \n \".\" expected, Found: "+lookahead);

        //Encontrando linea
        try {
            ArrayList<Integer> line = findLineOf(lookahead);
            System.out.println("Line: "+line);
        } catch (Exception ex) {
            Logger.getLogger(ScannerCocol.class.getName()).log(Level.SEVERE, null, ex);
        }


    }

}
public boolean match(String terminal){
    boolean result;
    if(terminal.equals("number")){
        result = automataNumber.simularAFN(lookahead, automataNumber.inicial, conjuntoSimbolos);
        return result;
    }
    else if(terminal.equals("ident")){
        result = automataident.simularAFN(lookahead,automataident.inicial,conjuntoSimbolos);
        return result;
    }
    else if(terminal.equals("string")){
       result =  automataString.simularAFN(lookahead,automataString.inicial,conjuntoSimbolos);
       return result;
    }   
    else if(terminal.equals("char")){
        result = automataChar.simularAFN(lookahead,automataChar.inicial,conjuntoSimbolos);
        return result;
    } 
    else{
        if(this.lookahead.equals(terminal)){
            lookahead= in.next();
            return true;
        }
        else{
            System.out.println("Error: Se esperaba: "+terminal);
            return false;
        }
    }

我面临的问题是我必须搜索0个或更多个生产派生的情况(例如在SetDecl上)。我知道我必须继续尝试匹配制作,直到我无法匹配,但我不知道如何在我必须继续阅读输入时报告错误。

有人能给我一些想法吗?

1 个答案:

答案 0 :(得分:1)

预测解析器的一个简单模型是与生产相对应的每个函数都返回一个布尔值(成功或失败)。然后是一个包含&#34;零或更多&#34;可以编写扩展,例如:

if(lookahead.equals("CHARACTERS")){
    match("CHARACTERS");
    while (SetDecl()) ;
    return true;
}
/* ... */

顺便说一下,定义一个消耗前瞻字符串的运算符实际上很方便:

if(lookahead.matches("CHARACTERS")){
    while (SetDecl()) ;
    return true;
}
/* ... */

lookahead.matches(s)基本上是if(lookahead.equals(s){match(s); return true;}else{return false;}

任何生产函数的一般规则是:

1)如果规则中的第一个对象(令牌或非终端)无法匹配,请保持输入不变并返回false。

2)如果规则中的任何其他对象无法匹配,则发出错误并尝试恢复。