来自 Github 的 Java 语法 for ANTLR4 和 C# 目标

本文关键字:ANTLR4 目标 for 语法 Github Java 来自 | 更新日期: 2023-09-27 18:36:42

我已经放弃了将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-'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

来自 Github 的 Java 语法 for ANTLR4 和 C# 目标

在 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)。