我正在为 COCOL/R 开发一个预测解析器
这是我现在正在尝试解析的语法部分:
方括号表示 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/