简体   繁体   English

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

[英]How to use Listener method in antlr4 to get the contents of parsers?

As far as I am concerned, the Listener method of antlr4 seems can only directly get the informations of TerminalNodes --- specifically the Lexer Nodes.就我而言,antlr4 的 Listener 方法似乎只能直接获取 TerminalNodes 的信息——特别是 Lexer Nodes。

However, now I am hoping to put out the information of Parser like this:但是,现在我希望像这样输出Parser的信息:

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

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

First of all, I want to figure out how to diirectly get the contents of primitiveType and put out the contents like byte or short without changing it to Lexer(TerminalNode).首先,我想弄清楚如何直接获取primitiveType的内容,并在不将其更改为Lexer(TerminalNode)的情况下将byteshort类的内容输出。 I've checked the code of aidlParser.java (aidl.g4 is my initial grammar file(我检查了aidlParser.java的代码(aidl.g4是我的初始语法文件(

Second, I want to know that if there is a way to know what actually a parser matches.其次,我想知道是否有办法知道解析器实际匹配的内容。 Eg I want to know which regulation(like primitiveType or referencedType ...) of type is used in matching a type in the grammar without having to visit each sub-node(actually the regulations in Lisenter method) of type and see which one contains something.例如,我想知道哪些法规(如primitiveTypereferencedType ...)的type是匹配的语法类型使用,而无需访问的每个子节点(实际上Lisenter法的规定) type ,看看哪一个包含东西。

Here is the entire code of my .g4 file:这是我的 .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
    ;

I would sincerely be grateful for your help in time!我将真诚地感谢您的及时帮助!

Once your parse run is over you will get a parse tree.一旦您的解析运行结束,您将获得一个解析树。 You can walk that tree down to the nodes you are interested in (usually you use a parse tree listener for that and only override the enter/exit* methods that are relevant for your problem).您可以将该树向下遍历到您感兴趣的节点(通常您为此使用解析树侦听器,并且仅覆盖与您的问题相关的 enter/exit* 方法)。 In your enterPrimitveType method you get an EnterPrimitiveTypeContext parameter.在您的enterPrimitveType方法中,您将获得一个EnterPrimitiveTypeContext参数。 Use its getText method to get the text it matched.使用它的getText方法来获取它匹配的文本。

For your second question you would do exactly the same, just use the enterType method instead.对于您的第二个问题,您会做完全相同的事情,只需使用enterType方法即可。 The EnterTypeContext parameter has members for each alternative in your rule. EnterTypeContext参数包含规则中每个备选方案的成员。 Check which one is not null to see which actually matched.检查哪个不为空以查看哪个实际匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM