Calling Listener recusrively for all the grammars even when there is no input.

36 views
Skip to first unread message

Smith

unread,
Jul 30, 2015, 2:40:19 AM7/30/15
to antlr-discussion

Hi,

If I have a ANTLR grammar file and custom Listener. And I would like to walk through the entire Parse Tree even when the input is empty. Is there any options ?

For ex:
My Grammar is
grammar MyExpr;


prog
: stat+ ;


stat
: expr NEWLINE #printExpr
| ID '=' expr NEWLINE #assign
| NEWLINE #blank
;
expr
: expr op=('*'|'/') expr #multiDiv
| expr op=('+'|'-') expr #AddSub
| INT #intgr
| ID #id
| '(' expr ')' #parenthesis
;


ID
: [a-zA-Z]+ ; // match identifiers
INT
: [0-9]+ ; // match integers
NEWLINE
:'\r'? '\n' ; // return newlines to parser (end-statement signal)
WS
: [ \t]+ -> skip ; // toss out whitespace


MUL
: '*' ; // assigns token name to '*' used above in grammar
DIV
: '/' ;
ADD
: '+' ;
SUB
: '-' ;

Code is.

                AntlrInputStream inputStream = new AntlrInputStream(""); // Note... I don't have any input
               
MyExprLexer lexer = new MyExprLexer(inputStream);
               
CommonTokenStream commonTokenStream = new CommonTokenStream(lexer);
               
MyExprParser parser = new MyExprParser(commonTokenStream);
               
MyListener listener = new MyListener();
                parser
.AddListener(listener);
               
IParseTree tree = parser.prog();   // ? I want this to go through all the listeners (EnterEveryRule API).



         
ParseTreeWalker walker = new ParseTreeWalker();
         walker
.Walk(listener , tree ); //  // ? I want this to go through all the listeners (EnterEveryRule API).


What am I asking is not the intended behavior in normal scenarios. What I am looking for is the way where based on the grammar, all the listeners are callled so that I could get the necessary expected tokens in the respective listeners even when input is empty.

Thank You.


  

               

Bence Erős

unread,
Jul 30, 2015, 5:26:52 AM7/30/15
to antlr-di...@googlegroups.com
Hello,

as far as I can understand you are trying to traverse the structure (BNF) of the language itself, instead of traversing the parse tree of a sentence in the language. This is probably something you won't be able to do with the listeners. So from this point of view it can be a better idea to
- parse your g4 file using the antlr4 grammar
- or traverse the listener methods using reflection



--
You received this message because you are subscribed to the Google Groups "antlr-discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to antlr-discussi...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Smith

unread,
Jul 30, 2015, 10:41:48 AM7/30/15
to antlr-discussion, smitha...@gmail.com
Thanks Bence Eros.

Thats very good.

I have tried the first option to parse the g4 file itself, however since I am using the C#.Net version of it, there seems to be java code written in AntlrV4Lexer file
https://github.com/antlr/grammars-v4/blob/9e613c79ebdcd96238fedad611916dac2ab7af23/antlr4/ANTLRv4Lexer.g4 which is referenced in Antlrv4Parser file. So I could not get it compiled. Is it possible to get this compiled in .Net environment ?

Will explore second possibilities you have mentioned i.e. using Reflection.

Thank You.

Smith

unread,
Jul 31, 2015, 6:06:51 AM7/31/15
to antlr-discussion, smitha...@gmail.com
All,

Finally I got this working by recursively calling Parser methods which in turn invokes the Listener methods. Thanks to Bence Eros!!
Below is the code and In the Listener, Overridden EnterEveryRule method to fill the map of ExpectedTokens againsta the index.

               
Assembly assembly = Assembly.GetExecutingAssembly();
               
Type parserClassType = assembly.GetType("CESample.MyGrammarParser");
               
if (parserClassType != null)
               
{
                   
MethodInfo[] methods = parserClassType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
                   
if (methods != null && methods.Count() > 0)
                   
{
                       
foreach (MethodInfo methodInfo in methods)
                       
{
                           
Debug.WriteLine(methodInfo.Name);
                           
object result = null;
                           
ParameterInfo[] parameters = methodInfo.GetParameters();
                           
if (parameters.Length == 0)
                           
{
                                result
= methodInfo.Invoke(_Parser, null);
                           
}                            
                       
}
                   
}
               
}



Not sure, if this is the right way. But it has worked for me now.


On Thursday, July 30, 2015 at 12:10:19 PM UTC+5:30, Smith wrote:
Reply all
Reply to author
Forward
0 new messages