Ysak
Ysak

Reputation: 2755

Generate a hashset of string list after ANTLR parse

I have a grammar as follows

grammar MyRule;

gatewayRuleExpr : useStat       #useStmtExpr
                | ifStmnt       #ifStmtExpr
                ;

offerRuleExpr : '(' offerRuleExpr ')'                       # parensExpr
           | left=offerRuleExpr 'and' right=offerRuleExpr   # andExpr
           | left=offerRuleExpr 'or' right=offerRuleExpr    # orExpr
           | simpleExpr                                     # clauseExpr
           ;

simpleExpr : TAG 'in' '(' stringList ')' ;

stringList : STRING (',' STRING)* ;
ifStmnt : 'if'  useCond  ('else' 'if' useCond ) * ('else' useStat)? ;
useCond : '(' offerRuleExpr ')' 'then' useStat ;
useStat : 'use' USE_TAG (orderStat)? 'from' '(' stringList ')';
orderStat: 'in' 'order' | 'in' 'reverse' 'order';

USE_TAG : 'gateway';
TAG : 'pay_type' | 'bank' | 'brand' | 'bin' | 'bin_group';
STRING : '\'' [A-Za-z0-9]* '\'';
WS: [ \t\r\n]+ -> skip ;

I could able to use it for the purpose.

When I generate the Java code the Parser includes A class named StringListContext which is the context for my stringList parser grammer.

Is there anyway given a expression

pay_type in ('NB','CC') and (brand in ('VISA','MASTER') or bank in('HDFC','CITI'))

I need the StringListContext to generate a function called getStringSet, which returns me a HashSet of the list value. I don't want the set to be created dynamically when I call the function, instead it should create it during the parsing time itself, and the call should return me the instance immediately. Is there a way that I can build this requirement using the grammar not manually altering the generated code.

Upvotes: 0

Views: 183

Answers (1)

GRosenberg
GRosenberg

Reputation: 6001

This answers your core question of how to get a HashSet at parse-time:

stringList 
    locals[Set<String> s = new HashSet<>()]
           : t+=STRING (',' t+=STRING)* { $s.addAll($t); }
           ;

Each instance of your StringListContext will contain a public variable 's' populated by the embedded action when the rule is matched. The Definitive Antlr4 Reference p268 covers this in detail.

To add a 'getStringSet' function, use the @members block. Let the function take a StringListContext instance as a parameter and return the value 's'.

Upvotes: 1

Related Questions