我已经放弃了将C#语法从ANTLR3.2版本修复到ANTLR4版本,现在我想制作Java Parser和Visitor。从Github下载的ANTLR4的Java语法:https://github.com/antlr/grammars-v4/blob/master/java/Java.g4 是为任何目标语言编写的,但有些代码是针对Java目标的,它不适用于C#。我说的是这些雷克沙规则:
fragment
JavaLetter
: [a-zA-Z$_] // these are the "java letters" below 0xFF
| // covers all characters above 0xFF which are not a surrogate
~[u0000-u00FFuD800-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-u00FFuD800-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 语言规范 §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 字母或数字"是方法
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
;
否则,为了获得完整的支持,您可以使用 C# 目标中的 Java-LR.g4 语法(在使用前重命名为 Java.g4)。