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

标签 java c# parsing antlr4 antlr4cs

我已经放弃将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 字母或数字”是一个字符,方法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/

相关文章:

c# - Lambda 表达式定义(学究)?

java - 在 Java 中使用 XML 解析器创建文档变量时出错

Java日期解析: distinguish between 28/10/2012 2:00 CET and 28/10/2012 2:00 CEST

java - 如何在代码中执行osgi命令

java - 在抽象类中 Autowiring 不同的bean

java - Liferay 门户的 LDAP 配置不起作用

java - Eclipse Juno 更新后无法创建服务器

c# - 在添加/删除项目时动态调整 ListView 高度?

javascript - OrientDB 在 JavaScript 中通过 Traverse 命令的输出进行解析

c# - 我如何告诉抽象类的模拟/ stub 使用它对 Object.Equals() 的覆盖?