Reputation: 2755
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
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