我已经放弃将C#语法从ANTLR3.2版本修复到ANTLR4版本,现在我想制作Java Parser和Visitor。 从 Github 下载的 ANTLR4 的 Java 语法:https://github.com/antlr/grammars-v4/blob/master/java/Java.g4是为任何目标语言编写的,但有些代码是针对 Java 目标的,它不适用于 C#。我正在谈论这些 lexar 规则:
fragment
JavaLetter
: [a-zA-Z$_] // these are the "java letters" below 0xFF
| // covers all characters above 0xFF which are not a surrogate
~[\u0000-\u00FF\uD800-\uDBFF]
// {Character.isJavaIdentifierStart(_input.LA(-1))}?
| // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
[\uD800-\uDBFF] [\uDC00-\uDFFF]
//{Character.isJavaIdentifierStart(Character.toCodePoint((char)_input.LA(-2), (char) _input.LA (-1)))}?
;
fragment
JavaLetterOrDigit
: [a-zA-Z0-9$_] // these are the "java letters or digits" below 0xFF
| // covers all characters above 0xFF which are not a surrogate
~[\u0000-\u00FF\uD800-\uDBFF]
// {Character.isJavaIdentifierPart(_input.LA(-1))}?
| // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
[\uD800-\uDBFF] [\uDC00-\uDFFF]
//{char.isJavaIdentifierPart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}?
;
我已经注释了以{Character.isJavaIdentifier...}开头的目标代码,现在可以了。我想知道为什么它在那里!我认为如果之前的标记或之前的 2 个标记(在 LA(-2) 的情况下)是 IdentifierPart,那么它会返回 true,但是操作代码的用途是什么?在 C# 中 Char 对象不支持静态方法 isIdentifierPart 或类似的方法...
我的问题是:如果我取消操作代码,解析器在解析 Java 输入代码期间是否会在特定标识符名称上失败? 如果是,我如何用它替换 C# 目标?
谢谢各位的回复! PK
最佳答案
在 Java Language Specification §3.8 ,标识符是根据 Character
上的两个静态方法定义的。类。
Identifier: IdentifierChars but not a Keyword or BooleanLiteral or NullLiteral IdentifierChars: JavaLetter {JavaLetterOrDigit} JavaLetter: any Unicode character that is a "Java letter" JavaLetterOrDigit: any Unicode character that is a "Java letter-or-digit"
“Java 字母”是一个字符,其方法
Character.isJavaIdentifierStart(int)
返回 true。“Java 字母或数字”是一个字符,方法
block 引用>Character.isJavaIdentifierPart(int)
返回 true。语法以一种特定的方式实现这一点,旨在最大限度地提高预期输入的性能。特别是该系列中最著名的角色
[a-zA-Z0-9_$]
(正则表达式语法)由语法直接处理。语言规范保证该集合始终被视为标识符字符。ANTLR 4 不会缓存 U+007F 以上 UTF-16 代码单元的 DFA 转换,因此前面描述的集合之外的任何内容无论如何都位于词法分析器的“慢速”路径上。这些字符是使用干净且简单的语义谓词来处理的,而不是扩大状态机的大小。
如果您的源代码不使用 U+007F 以上的代码点作为 Unicode 标识符,那么您可以安全地将语法简化为以下内容:
fragment JavaLetter : [a-zA-Z$_] // these are the "java letters" below 0xFF ; fragment JavaLetterOrDigit : [a-zA-Z0-9$_] // these are the "java letters or digits" below 0xFF ;
否则,要获得完整支持,您可以使用 Java-LR.g4来自 C# 目标的语法(使用前重命名为 Java.g4)。
关于来自 Github 的 ANTLR4 和 C# 目标的 Java 语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27826696/