我已经放弃了从ANTLR3.2的版本到ANTLR4的版本修复C#语法,现在我想制作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
答案 0 :(得分:2)
在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"
A" Java letter"是方法
Character.isJavaIdentifierStart(int)
返回true的字符。A" 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 )。