Unicode ANTLR4:在令牌规则中使用非ASCII字符

Unicode ANTLR4:在令牌规则中使用非ASCII字符,unicode,antlr,token,grammar,antlr4,Unicode,Antlr,Token,Grammar,Antlr4,在ANTRL4书的第74页上,它说任何Unicode字符都可以在语法中使用,只需以以下方式指定其代码点: '\uxxxx' 其中,xxxx是Unicode码点的十六进制值 因此,我在ID令牌的令牌规则中使用了该技术: grammar ID; id : ID EOF ; ID : ('a' .. 'z' | 'A' .. 'Z' | '\u0100' .. '\u017E')+ ; WS : [ \t\r\n]+ -> skip ; 当我尝试分析此输入时: Gŭnter ANTLR

在ANTRL4书的第74页上,它说任何Unicode字符都可以在语法中使用,只需以以下方式指定其代码点:

'\uxxxx'
其中,
xxxx
是Unicode码点的十六进制值

因此,我在ID令牌的令牌规则中使用了该技术:

grammar ID;

id : ID EOF ;

ID : ('a' .. 'z' | 'A' .. 'Z' | '\u0100' .. '\u017E')+ ;
WS : [ \t\r\n]+ -> skip ;
当我尝试分析此输入时:

Gŭnter
ANTLR抛出一个错误,表示它无法识别
ŭ
。(ŭ字符为十六进制016D,因此在规定范围内)


请问我做错了什么?

ANTLR准备接受16位字符,但默认情况下,许多地区将以字节(8位)的形式读取字符。在使用Java库读取文件时,需要指定适当的编码。如果您使用的是
TestRig
,可能是通过别名/script
grun
,那么可以使用参数
-编码utf-8
或其他方式。如果查看该类的源代码,您将看到以下机制:

InputStream is = new FileInputStream(inputFile);
Reader r = new InputStreamReader(is, encoding); // e.g., euc-jp or utf-8
ANTLRInputStream input = new ANTLRInputStream(r);
XLexer lexer = new XLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
...

对于那些在java代码中使用antlr4存在相同问题的人,
AntlInputStream
Being不推荐使用,下面是一种将多字符unicode数据从
String
传递到
MyLexer
lexer的有效方法:

String myString=“\u2013”;
CharBuffer CharBuffer=CharBuffer.wrap(myString.toCharArray());
CodePointBuffer CodePointBuffer=CodePointBuffer.withChars(charBuffer);
CodePointCharStream cpcs=CodePointCharStream.fromBuffer(codePointBuffer);
OneLexer lexer=新的MyLexer(cpcs);
CommonTokenStream令牌=新的CommonTokenStream(lexer);
语法:

名称:
[A-Za-z][0-9A-Za-z\u0080-\uFFFF_008;]+
;
爪哇:

import org.antlr.v4.runtime.CharStream;
导入org.antlr.v4.runtime.CharStreams;
导入org.antlr.v4.runtime.CommonTokenStream;
导入org.antlr.v4.runtime.TokenStream;
导入com.thalesgroup.dms.stimulisparser.SystemContext;
最终类需求解析器{
静态SystemContext解析(字符串要求){
requirement=requirement.replaceAll(“\t”和“);
final CharStream CharStream=CharStreams.fromString(要求);
最终刺激器lexer=新刺激器(charStream);
最终令牌流令牌=新的CommonTokenStream(lexer);
最终刺激器解析器=新刺激器(令牌);
final SystemContext system=parser.system();
if(parser.getNumberOfSyntaxErrors()>0){
格式(要求);
}
返回系统;
}
私有RequirementParser(){/**/}
}
资料来源:


谢谢!在调用TestRig:java org.antlr.v4.runtime.misc.TestRig-encoding UTF-8 ID.g4时,我尝试添加-encoding标志,但是,这导致了以下错误:无法将-encoding作为lexer或解析器建议加载?您的语法中没有使用TestRig。这就是antlr的作用。-根据我的回答,编码将继续进行。
java-Dfile.encoding=UTF-8 org.antlr.v4.runtime.misc.TestRig ID…
谢谢Gunther。我尝试了一下,但它给出了相同的错误消息:不能像lexer或parser那样加载编码。