如何在antlr4中使用Listener方法获取解析器的内容?

问题描述 投票:1回答:1

就我而言,antlr4的Listener方法似乎只能直接获取TerminalNodes的信息-尤其是Lexer Nodes。

但是,现在我希望像这样发布解析器的信息:

type : 
        primitiveType
    |   referencedType
    |   arrayType
    |   listType
    |   mapType
    |   'void'
    ;

primitiveType : 
        'byte'
    |   'short'
    |   'int'
    |   'long'
    |   'char'  
    |   'float'
    |   'double'
    |   'boolean'
    ;
referencedType : 
        'String'
    |   'CharSequence'
    |   selfdefineType
    ;

首先,我想弄清楚如何直接获取primitiveType的内容并输出byteshort之类的内容,而不将其更改为Lexer(TerminalNode)。我检查了aidlParser.java的代码(aidl.g4是我的初始语法文件(

其次,我想知道是否有一种方法可以知道解析器实际匹配的内容。例如,我想知道primitiveType的哪个规则(例如referencedTypetype ...)用于匹配语法中的类型,而不必访问每个子节点(实际上是Lisenter方法中的规则) type,然后查看其中一个包含什么。

这是我的.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-\u007F\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 0x7F
    |   // covers all characters above 0x7F which are not a surrogate
        ~[\u0000-\u007F\uD800-\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  :  [ \t\r\n\u000C]+ -> skip
    ;

我将非常感谢您的及时帮助!

parsing antlr antlr4 lexer
1个回答
0
投票

解析运行结束后,您将获得一个解析树。您可以将该树向下移动到您感兴趣的节点(通常您使用解析树侦听器,仅覆盖与您的问题相关的enter / exit *方法)。在您的enterPrimitveType方法中,您将获得一个EnterPrimitiveTypeContext参数。使用它的toString方法获取匹配的文本。

对于第二个问题,您将执行完全相同的操作,只需使用enterType方法即可。 EnterTypeContext参数具有规则中每个备用项的成员。检查哪一个不为null,以查看哪一个真正匹配。

© www.soinside.com 2019 - 2024. All rights reserved.