java - Cocol/R 预测解析器实现 Java

标签 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 上)。我知道我必须继续尝试匹配产品,直到我无法匹配为止,但我不知道如何辨别何时必须报告错误以及何时必须继续读取输入。

谁能给我一些想法吗?

最佳答案

预测解析器的一个简单模型是,与产生式相对应的每个函数都返回一个 boolean 值(成功或失败)。然后可以编写包含“零个或多个”扩展的规则,例如:

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) 如果规则中的第一个对象( token 或非终结符)无法匹配,则保持输入不变并返回 false。

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

关于java - Cocol/R 预测解析器实现 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25678403/

相关文章:

parsing - 使用 Parsec 写入 Read 实例

java - 如何将变量值从一个 JFrame 传递到 Netbeans 中的另一个 JFrame

java - 使用 collections.sort 按字母顺序对构造对象列表进行排序

java - 在 GUI 中调整 JTable 中的列大小

java - JScrollPane 中的 JLabels

string - Rust 有类似 scanf 的东西吗?

python - "Deparsing"使用 pyparsing 的列表

android - 从 Android 中的 Parcelable 数组中获取值(value)

php - 添加 WHERE、SELECT、ORDER BY 等...就像通过 PHP 的链式 SQL

java - Liferay 错误 [RuntimePageImpl-16] 不是有效的包含