I am trying a get semantic predicate to work. This seems straight forward but somehow doesn't work, based on a boolean condition I need to either execute a rule (which spits out an AST) or just or manually construct one
below is the parser rule.
displayed_column
:
{columnAliases.containsKey($text)}?
=>-> ^(PROPERTY_LIST ^(PROPERTY IDENTIFIER[columnAliases.get($text)]))
| sql_expression
;
I have tried all gated and disambiguating as well but while running through the code, it always goes to the second rule (sql_expression).
Can anyone please help me out ?
Thanks
EDIT: I just realized that $text is empty while the predicate is running which is why its always matching the second rule. I changed the rule to this and it works
displayed_column
:
sql_expression
-> {columnAliases.containsKey($text)}? ^(PROPERTY_LIST ^(PROPERTY IDENTIFIER[columnAliases.get($text)]))
-> sql_expression
However I ran into a different problem now, I realized that manually constructing the tree will not work, I need to re-run the rule displayed_column again with the new text (value from columnAliases Map), is that possible?
This was my original question https://stackguides.com/questions/14170541/antlr-dynamic-input-stream-modification-during-parsing
Basically I am trying to interactively parse and interpret sql like statments ex:
select a.b.c from pool;
select min(abc.def[*]) from pool;
Since the column names might be a bit long I have given the user a preference to alias column names (through a different command), for example the user might set a preference and then run his commands
set column_alias a.b.c d;
select d from pool;
Now while parsing I inject the preferences (Map) into the generated parser and I am trying to replace/map the new column back to the original column and then continue interpreting. Handling it in the parser seemed like the only option to me since I thought it would be difficult to do it the tree grammer since the column spans multiple rules.
I could post the entire grammar but its a bit too long, here is a scaled down version of it
select_stmt:
: 'select' displayed_column 'from' pool
;
displayed_column
: sql_expression
;
sql_expression
: term ( (PLUS^ | MINUS^) term)*
;
term : factor ( (ASTERISK^ | DIVIDE^) factor)*
;
... <more_rules> ...
I am stuck on this, using string template to output a translated statement and then reparse seems like the only option to me, but this would entail rewriting the entire grammar to output templates (right now I have a combined grammar with outputs an AST and a tree grammar that interprets it). It would be greatly appreciated if someone can tell me way which is less intrusive.
Thanks again.
sql_expression
(the second alternative). So, matching nothing will only letcolumnAliases.containsKey($text)
evaluate totrue
if yourMap
(assuming it is aMap
) contains an empty string as key. Could you provide some more context? Possibly give some example input strings and desired AST's as output? – Bart Kiers