就我而言,antlr4的Listener方法似乎只能直接获取TerminalNodes的信息,特别是Lexer Nodes。
然而,现在我希望发布这样的Parser信息:
type :
primitiveType
| referencedType
| arrayType
| listType
| mapType
| 'void'
;
primitiveType :
'byte'
| 'short'
| 'int'
| 'long'
| 'char'
| 'float'
| 'double'
| 'boolean'
;
referencedType :
'String'
| 'CharSequence'
| selfdefineType
;
首先,我想弄清楚如何直接获得primitiveType
的内容,并在不将其更改为Lexer(TerminalNode(的情况下发出类似byte
或short
的内容。我已经检查了aidlParser.java
的代码(aidl.g4是我的初始语法文件(
其次,我想知道是否有一种方法可以知道解析器实际匹配的内容。例如,我想知道type
的哪条规则(比如primitiveType
或referencedType
…(用于匹配语法中的类型,而不必访问type
的每个子节点(实际上是Lisenter方法中的规则(,看看哪条规则包含什么。
这是我的.g4文件的全部代码:
grammar aidl;
//parser
//file
file : packageDeclaration* importDeclaration* parcelableDeclaration? interfaceDeclaration? ;
//packageDeclaration
packageDeclaration :'package' packageName ';';
packageName : Identifier
|
packageName '.' Identifier;
// importDeclaration
importDeclaration
: 'import' importName ';'
;
importName : Identifier
|
importName '.' Identifier;
//parcelableDeclaration
parcelableDeclaration : 'parcelable' parcelableName ';' ;
parcelableName : Identifier ;
//interfaceDeclaration
interfaceDeclaration : interfaceTag? 'interface' interfaceName '{' methodsDeclaration+ '}' ;
interfaceTag : 'oneway' ;
interfaceName : Identifier ;
// methodsDeclaration
methodsDeclaration : methodTag? returnType methodName '(' parameters? ')' ';' ;
methodName : Identifier ;
methodTag: 'oneway';
returnType : type ;
// parameters
parameters
: parameter (',' parameter)*
;
parameter
: parameterTag? parameterType parameterName ;
parameterType : type ;
parameterName : Identifier;
parameterTag : 'in' | 'out' | 'inout' ;
// type
type :
primitiveType
| referencedType
| arrayType
| listType
| mapType
| 'void'
;
primitiveType :
'byte'
| 'short'
| 'int'
| 'long'
| 'char'
| 'float'
| 'double'
| 'boolean'
;
referencedType :
'String'
| 'CharSequence'
| selfdefineType
;
selfdefineType : Identifier;
arrayType : primitiveType dims
| referencedType dims
;
listType : 'List' ('<' (primitiveType | referencedType) (',' (primitiveType | referencedType))* '>')?;
mapType : 'Map' ('<' (primitiveType | referencedType) (',' (primitiveType | referencedType))* '>')?;
dims
: '[' ']' ( '[' ']')*
;
//Lexer
// Identifier
Identifier
: JavaLetter JavaLetterOrDigit*
;
fragment
JavaLetter
: [a-zA-Z$_] // these are the "java letters" below 0x7F
| // covers all characters above 0x7F which are not a surrogate
~[u0000-u007FuD800-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 0x7F
| // covers all characters above 0x7F which are not a surrogate
~[u0000-u007FuD800-uDBFF]
{Character.isJavaIdentifierPart(_input.LA(-1))}?
| // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
[uD800-uDBFF] [uDC00-uDFFF]
{Character.isJavaIdentifierPart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}?
;
WS : [ trnu000C]+ -> skip
;
我将衷心感谢你的及时帮助!
解析运行结束后,您将获得一个解析树。您可以将该树向下遍历到感兴趣的节点(通常使用解析树侦听器,只覆盖与问题相关的enter/exit*方法(。在enterPrimitveType
方法中,您将获得一个EnterPrimitiveTypeContext
参数。使用其getText
方法来获取与其匹配的文本。
对于您的第二个问题,您也可以使用完全相同的方法,只需使用enterType
方法即可。EnterTypeContext
参数为规则中的每个备选方案都有成员。检查哪一个不为空,看看哪一个实际匹配。