我正在尝试将ANTLR定义的语法集成到NetBeans中,到目前为止,有效的语法工作正常。但是,当前如果输入任何未在某处语言中定义的字符(例如,“?”字符),自定义编辑器会立即崩溃,因为它无法找到该字符的规则。
在ANTLR中是否有一种方法可以捕获并跳过与规则不匹配的每个字符(并且可能输出错误消息)而不会让整个词法分析器崩溃并烧毁?我想标记无效字符,跳过它们,然后继续lexing,例如:
//some rules + tokens
invalidCharacter
: <<catch all other characters>>
{System.out.println("undefined character entered!")}
;
任何帮助都会得到解决。
答案 0 :(得分:6)
如果你只对词法分析器中的非法字符感兴趣,那么这样简单的事情可能对你有所帮助:
grammar T;
@lexer::members {
public List<String> errors = new ArrayList<String>();
}
parse
: .* EOF
;
INT
: '0'..'9'+
;
WORD
: ('a'..'z' | 'A'..'Z')+
;
SPACE
: ' ' {$channel=HIDDEN;}
;
INVALID
: . {
errors.add("Invalid character: '" + $text + "' on line: " +
getLine() + ", index: " + getCharPositionInLine());
}
;
如您所见,只接受整数和ascii字,所有其他字符都会导致错误被添加到词法分析器内的List
。使用测试类解析类似"abc 123 ? foo !"
的字符串时:
import org.antlr.runtime.*;
public class Main {
public static void main(String[] args) throws Exception {
TLexer lexer = new TLexer(new ANTLRStringStream("abc 123 ? foo !"));
CommonTokenStream tokens = new CommonTokenStream(lexer);
tokens.toString(); // dummy call to toString() which causes all tokens to be created
if(!lexer.errors.isEmpty()) {
for(String error : lexer.errors) {
System.out.println(error);
}
}
else {
TParser parser = new TParser(tokens);
parser.parse();
}
}
}
将导致以下输出:
java -cp antlr-3.3.jar org.antlr.Tool T.g javac -cp antlr-3.3.jar *.java java -cp .:antlr-3.3.jar Main Invalid character: '?' on line: 1, index: 9 Invalid character: '!' on line: 1, index: 15