Reputation: 5787
I have a rule called "variable" which is just associated with non-keyword text. During runtime I compile a list of strings that should be associated with the rule "special" which is also just normal text however it is defined below variable, hence is never actually reached as everything will match to variable first.
During runtime how can I use this list to change any tokens matching "variable" that are also in the list to match "special"?
Example:
Grammar
parent:
variable |
special;
variable:
ID;
special:
ID;
Text to be parsed: "one two three four"
Result: variable, variable, variable, variable
Later I calculate that I want "four" to be associated with special. So the result should change to: variable, variable, variable, special
This should happen without the text actually changing. I tried looking into listeners and visitors but I'm not sure how I would actually modify the rule associated with a node. I also found this example that seems similar but it's in ANTLR3: Dynamically create lexer rule
Upvotes: 0
Views: 652
Reputation: 5991
The perhaps most direct way of qualifying a token at run-time is to use a predicate to selectively falsify a rule. This can be done in either in the parser or lexer. Using your proto-grammar, and rearranging a bit:
@members {
ArrayList<String> keyList = .... // get dynamic list of keywords
public boolean inList(String id) {
return keyList.contains(id) ;
}
}
parent : special // dynamic keywords
| variable // everything else
;
special : ID { inList($ID.getText()) }? ;
variable : ID ;
The predicate falsifies the special
rule for any ID token not in the list of dynamic keywords.
Upvotes: 1